diff --git a/lib/utils/action-utils.js b/lib/utils/action-utils.js --- a/lib/utils/action-utils.js +++ b/lib/utils/action-utils.js @@ -461,4 +461,5 @@ createBoundServerCallsSelector, registerActiveSocket, useServerCall, + bindCookieAndUtilsIntoCallServerEndpoint, }; diff --git a/lib/utils/keyserver-call.js b/lib/utils/keyserver-call.js new file mode 100644 --- /dev/null +++ b/lib/utils/keyserver-call.js @@ -0,0 +1,107 @@ +// @flow + +import * as React from 'react'; +import { useDispatch } from 'react-redux'; + +import { bindCookieAndUtilsIntoCallServerEndpoint } from './action-utils.js'; +import type { CallServerEndpointOptions } from './call-server-endpoint.js'; +import { useSelector } from './redux-utils.js'; +import type { Endpoint } from '../types/endpoints.js'; +import type { KeyserverInfo } from '../types/keyserver-types.js'; +import type { Dispatch } from '../types/redux-types.js'; +import type { CurrentUserInfo } from '../types/user-types.js'; + +export type CallKeyserverEndpoint> = ( + endpoint: Endpoint, + input: { +[string]: mixed }, + args: Args, + options?: ?CallServerEndpointOptions, +) => Promise; + +export type ActionFunc, Return> = ( + callServerEndpoint: CallKeyserverEndpoint, +) => (...Args) => Promise; + +export type KeyserverCallConfig> = + | { +keyserverSelection: 'fanout' } + | { + +keyserverSelection: 'specific', + +keyserverIDExtractor: (...Args) => string, + }; + +export type KeyserverCall, Return> = { + +actionFunc: ActionFunc, + +config: KeyserverCallConfig, +}; + +export type ExtractAndBindCookieAndUtilsParams< + Args: $ReadOnlyArray, + Return, +> = { + +dispatch: Dispatch, + +currentUserInfo: ?CurrentUserInfo, + +keyserverInfos: { +[keyserverID: string]: KeyserverInfo }, + +keyserverCall: KeyserverCall, +}; + +function getCallKeyserverEndpoint, Return>( + params: ExtractAndBindCookieAndUtilsParams, +): CallKeyserverEndpoint { + const { dispatch, keyserverInfos, currentUserInfo, keyserverCall } = params; + + const { config: serverCallConfig } = keyserverCall; + + return ( + endpoint: Endpoint, + data: Object, + args: Args, + options?: ?CallServerEndpointOptions, + ) => { + // TODO + if (serverCallConfig.keyserverSelection === 'fanout') { + return Promise.resolve(undefined); + } + const keyserverID = serverCallConfig.keyserverIDExtractor(...args); + const { + cookie, + urlPrefix, + sessionID, + connection, + lastCommunicatedPlatformDetails, + } = keyserverInfos[keyserverID]; + + const boundCallServerEndpoint = bindCookieAndUtilsIntoCallServerEndpoint({ + dispatch, + currentUserInfo, + cookie, + urlPrefix, + sessionID, + connectionStatus: connection.status, + lastCommunicatedPlatformDetails, + }); + return boundCallServerEndpoint(endpoint, data, options); + }; +} + +function useKeyserverCall, Return>( + keyserverCall: KeyserverCall, + paramOverride?: ?$Shape>, +): (...Args) => Promise { + const dispatch = useDispatch(); + const keyserverInfos = useSelector( + state => state.keyserverStore.keyserverInfos, + ); + const currentUserInfo = useSelector(state => state.currentUserInfo); + return React.useMemo(() => { + const callKeyserverEndpoint = getCallKeyserverEndpoint({ + dispatch, + currentUserInfo, + keyserverInfos, + keyserverCall, + ...paramOverride, + }); + return keyserverCall.actionFunc(callKeyserverEndpoint); + }, [dispatch, currentUserInfo, keyserverInfos, keyserverCall, paramOverride]); +} + +export { useKeyserverCall };