diff --git a/lib/keyserver-conn/keyserver-call-infos.js b/lib/keyserver-conn/keyserver-call-infos.js index 476ef132d..16c17e841 100644 --- a/lib/keyserver-conn/keyserver-call-infos.js +++ b/lib/keyserver-conn/keyserver-call-infos.js @@ -1,56 +1,56 @@ // @flow import { createSelector } from 'reselect'; import { useDerivedObject } from '../hooks/objects.js'; import type { PlatformDetails } from '../types/device-types.js'; import type { KeyserverInfo } from '../types/keyserver-types.js'; export type KeyserverInfoPartial = $ReadOnly<{ ...Partial, +urlPrefix: $PropertyType, }>; -export type KeyserverCallInfo = { +type KeyserverCallInfo = { +cookie: ?string, +urlPrefix: string, +sessionID: ?string, +isSocketConnected: boolean, +lastCommunicatedPlatformDetails: ?PlatformDetails, }; const createKeyserverCallSelector: () => KeyserverInfoPartial => KeyserverCallInfo = () => createSelector( (keyserverInfo: KeyserverInfoPartial) => keyserverInfo.cookie, (keyserverInfo: KeyserverInfoPartial) => keyserverInfo.urlPrefix, (keyserverInfo: KeyserverInfoPartial) => keyserverInfo.sessionID, (keyserverInfo: KeyserverInfoPartial) => keyserverInfo.connection?.status === 'connected', (keyserverInfo: KeyserverInfoPartial) => keyserverInfo.lastCommunicatedPlatformDetails, ( cookie: ?string, urlPrefix: string, sessionID: ?string, isSocketConnected: boolean, lastCommunicatedPlatformDetails: ?PlatformDetails, ) => ({ cookie, urlPrefix, sessionID, isSocketConnected, lastCommunicatedPlatformDetails, }), ); function useKeyserverCallInfos(keyserverInfos: { +[keyserverID: string]: KeyserverInfoPartial, }): { +[keyserverID: string]: KeyserverCallInfo } { return useDerivedObject( keyserverInfos, createKeyserverCallSelector, ); } export { useKeyserverCallInfos }; diff --git a/lib/utils/keyserver-call.js b/lib/utils/keyserver-call.js index ae8ad5891..6d86b8d78 100644 --- a/lib/utils/keyserver-call.js +++ b/lib/utils/keyserver-call.js @@ -1,148 +1,121 @@ // @flow import _memoize from 'lodash/memoize.js'; import * as React from 'react'; import type { CallServerEndpointOptions } from './call-server-endpoint.js'; import { promiseAll } from './promises.js'; import { useSelector, useDispatch } from './redux-utils.js'; import { useCallKeyserverEndpointContext } from '../keyserver-conn/call-keyserver-endpoint-provider.react.js'; import { useKeyserverCallInfos, type KeyserverInfoPartial, - type KeyserverCallInfo, } from '../keyserver-conn/keyserver-call-infos.js'; import type { Endpoint } from '../types/endpoints.js'; import type { Dispatch } from '../types/redux-types.js'; import type { CurrentUserInfo } from '../types/user-types.js'; export type CallKeyserverEndpoint = ( endpoint: Endpoint, requests: { +[keyserverID: string]: ?{ +[string]: mixed } }, options?: ?CallServerEndpointOptions, ) => Promise<{ +[keyserverID: string]: any }>; 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; -type BindCallKeyserverSelector = ( - keyserverCall: ActionFunc, -) => Args => Promise; -function useBindCallKeyserverEndpointSelector( - dispatch: Dispatch, - currentUserInfo: ?CurrentUserInfo, - keyserverCallInfos: { +[keyserverID: string]: KeyserverCallInfo }, -): BindCallKeyserverSelector { - const { createCallSingleKeyserverEndpointSelector } = - useCallKeyserverEndpointContext(); - const getCallSingleKeyserverEndpointSelector: typeof createCallSingleKeyserverEndpointSelector = - React.useMemo( - () => _memoize(createCallSingleKeyserverEndpointSelector), - [createCallSingleKeyserverEndpointSelector], - ); - return React.useMemo( - () => - _memoize( - ( - keyserverCall: ActionFunc, - ): (Args => Promise) => { - const callKeyserverEndpoint = ( - endpoint: Endpoint, - requests: { +[keyserverID: string]: ?{ +[string]: mixed } }, - options?: ?CallServerEndpointOptions, - ) => { - const makeCallToSingleKeyserver = (keyserverID: string) => { - const { - cookie, - urlPrefix, - sessionID, - isSocketConnected, - lastCommunicatedPlatformDetails, - } = keyserverCallInfos[keyserverID]; - - const boundCallServerEndpoint = - getCallSingleKeyserverEndpointSelector(keyserverID)({ - dispatch, - currentUserInfo, - cookie, - urlPrefix, - sessionID, - isSocketConnected, - lastCommunicatedPlatformDetails, - }); - - return boundCallServerEndpoint( - endpoint, - requests[keyserverID], - options, - ); - }; - - const promises: { [string]: Promise } = {}; - for (const keyserverID in requests) { - promises[keyserverID] = makeCallToSingleKeyserver(keyserverID); - } - return promiseAll(promises); - }; - const keyserverIDs = Object.keys(keyserverCallInfos); - return keyserverCall(callKeyserverEndpoint, keyserverIDs); - }, - ), - [ - dispatch, - currentUserInfo, - keyserverCallInfos, - getCallSingleKeyserverEndpointSelector, - ], - ); -} - export type KeyserverCallParamOverride = Partial<{ +dispatch: Dispatch, +currentUserInfo: ?CurrentUserInfo, +keyserverInfos: { +[keyserverID: string]: KeyserverInfoPartial }, }>; function useKeyserverCall( keyserverCall: ActionFunc, paramOverride?: ?KeyserverCallParamOverride, ): Args => Promise { const baseDispatch = useDispatch(); const baseCurrentUserInfo = useSelector(state => state.currentUserInfo); const keyserverInfos = useSelector( state => state.keyserverStore.keyserverInfos, ); const baseCombinedInfo = { dispatch: baseDispatch, currentUserInfo: baseCurrentUserInfo, keyserverInfos, ...paramOverride, }; const { dispatch, currentUserInfo, keyserverInfos: keyserverInfoPartials, } = baseCombinedInfo; const keyserverCallInfos = useKeyserverCallInfos(keyserverInfoPartials); - const bindCallKeyserverEndpointToAction = - useBindCallKeyserverEndpointSelector( - dispatch, - currentUserInfo, - keyserverCallInfos, + const { createCallSingleKeyserverEndpointSelector } = + useCallKeyserverEndpointContext(); + const getCallSingleKeyserverEndpointSelector: typeof createCallSingleKeyserverEndpointSelector = + React.useMemo( + () => _memoize(createCallSingleKeyserverEndpointSelector), + [createCallSingleKeyserverEndpointSelector], ); - return React.useMemo( - () => bindCallKeyserverEndpointToAction(keyserverCall), - [bindCallKeyserverEndpointToAction, keyserverCall], - ); + return React.useMemo(() => { + const callKeyserverEndpoint = ( + endpoint: Endpoint, + requests: { +[keyserverID: string]: ?{ +[string]: mixed } }, + options?: ?CallServerEndpointOptions, + ) => { + const makeCallToSingleKeyserver = (keyserverID: string) => { + const { + cookie, + urlPrefix, + sessionID, + isSocketConnected, + lastCommunicatedPlatformDetails, + } = keyserverCallInfos[keyserverID]; + + const boundCallServerEndpoint = getCallSingleKeyserverEndpointSelector( + keyserverID, + )({ + dispatch, + currentUserInfo, + cookie, + urlPrefix, + sessionID, + isSocketConnected, + lastCommunicatedPlatformDetails, + }); + + return boundCallServerEndpoint( + endpoint, + requests[keyserverID], + options, + ); + }; + + const promises: { [string]: Promise } = {}; + for (const keyserverID in requests) { + promises[keyserverID] = makeCallToSingleKeyserver(keyserverID); + } + return promiseAll(promises); + }; + const keyserverIDs = Object.keys(keyserverCallInfos); + return keyserverCall(callKeyserverEndpoint, keyserverIDs); + }, [ + dispatch, + currentUserInfo, + keyserverCallInfos, + getCallSingleKeyserverEndpointSelector, + keyserverCall, + ]); } export { useKeyserverCall };