diff --git a/lib/utils/keyserver-call.js b/lib/utils/keyserver-call.js --- a/lib/utils/keyserver-call.js +++ b/lib/utils/keyserver-call.js @@ -11,6 +11,7 @@ CallServerEndpoint, CallServerEndpointOptions, } from './call-server-endpoint.js'; +import { promiseAll } from './promises.js'; import { useSelector } from './redux-utils.js'; import type { PlatformDetails } from '../types/device-types.js'; import type { Endpoint } from '../types/endpoints.js'; @@ -19,28 +20,19 @@ import type { ConnectionStatus } from '../types/socket-types.js'; import type { CurrentUserInfo } from '../types/user-types.js'; -export type CallKeyserverEndpoint> = ( +export type CallKeyserverEndpoint = ( endpoint: Endpoint, - input: { +[string]: mixed }, - args: Args, + requests: { +[string]: mixed }, options?: ?CallServerEndpointOptions, -) => Promise; +) => Promise<{ +[id: string]: any }>; -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 ActionFunc = ( + callServerEndpoint: CallKeyserverEndpoint, + // The second argument is only used in actions that call all keyservers, + // and the request to all keyservers are exactly the same. + // An example of such action is fetchEntries. + allKeyserverIDs: $ReadOnlyArray, +) => Args => Promise; // _memoize memoizes the function by caching the result. // The first argument of the memoized function is used as the map cache key. @@ -87,11 +79,6 @@ +keyserverInfos: { +[keyserverID: string]: KeyserverInfo }, }; -export type GetCallKeyserverEndpointParams> = { - ...BindKeyserverCallParams, - +keyserverCallConfig: KeyserverCallConfig, -}; - const bindCallKeyserverEndpointSelector = createSelector( (state: BindKeyserverCallParams) => state.dispatch, (state: BindKeyserverCallParams) => state.currentUserInfo, @@ -102,55 +89,59 @@ keyserverInfos: { +[keyserverID: string]: KeyserverInfo }, ) => { return _memoize( - , Return>( - keyserverCall: KeyserverCall, - ): ((...Args) => Promise) => { + ( + keyserverCall: ActionFunc, + ): (Args => Promise) => { const callKeyserverEndpoint = ( endpoint: Endpoint, - data: Object, - args: Args, + requests: { +[id: string]: Object }, options?: ?CallServerEndpointOptions, ) => { - // TODO - if (keyserverCall.config.keyserverSelection === 'fanout') { - return Promise.resolve(undefined); + const bindCallKeyserverEndpoint = (keyserverID: string) => { + const { + cookie, + urlPrefix, + sessionID, + connection, + lastCommunicatedPlatformDetails, + } = keyserverInfos[keyserverID]; + + const boundCallServerEndpoint = createBoundServerCallsSelector( + keyserverID, + )({ + dispatch, + currentUserInfo, + cookie, + urlPrefix, + sessionID, + connectionStatus: connection.status, + lastCommunicatedPlatformDetails, + }); + + return boundCallServerEndpoint( + endpoint, + requests[keyserverID], + options, + ); + }; + + const promises = {}; + for (const keyserverID in requests) { + promises[keyserverID] = bindCallKeyserverEndpoint(keyserverID); } - const keyserverID = keyserverCall.config.keyserverIDExtractor( - ...args, - ); - const { - cookie, - urlPrefix, - sessionID, - connection, - lastCommunicatedPlatformDetails, - } = keyserverInfos[keyserverID]; - - const boundCallServerEndpoint = createBoundServerCallsSelector( - keyserverID, - )({ - dispatch, - currentUserInfo, - cookie, - urlPrefix, - sessionID, - connectionStatus: connection.status, - lastCommunicatedPlatformDetails, - }); - - return boundCallServerEndpoint(endpoint, data, options); + return promiseAll(promises); }; - - return keyserverCall.actionFunc(callKeyserverEndpoint); + const keyserverIDs = Object.keys(keyserverInfos); + return keyserverCall(callKeyserverEndpoint, keyserverIDs); }, ); }, ); -function useKeyserverCall, Return>( - keyserverCall: KeyserverCall, +function useKeyserverCall( + keyserverCall: ActionFunc, paramOverride?: ?$Shape, -): (...Args) => Promise { +): Args => Promise { const dispatch = useDispatch(); const keyserverInfos = useSelector( state => state.keyserverStore.keyserverInfos,