diff --git a/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js b/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js --- a/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js +++ b/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js @@ -4,6 +4,7 @@ import * as React from 'react'; import { createSelector } from 'reselect'; +import { useKeyserverCallInfos } from './keyserver-call-infos.js'; import { setNewSession } from './keyserver-conn-types.js'; import { canResolveKeyserverSessionInvalidation, @@ -20,12 +21,17 @@ CallSingleKeyserverEndpointOptions, } from '../utils/call-single-keyserver-endpoint.js'; import callSingleKeyserverEndpoint from '../utils/call-single-keyserver-endpoint.js'; +import { useSelector, useDispatch } from '../utils/redux-utils.js'; type CreateCallSingleKeyserverEndpointSelector = ( keyserverID: string, ) => ServerCallSelectorParams => CallSingleKeyserverEndpoint; +type GetCallSingleKeyserverEndpoint = ( + keyserverID: string, +) => CallSingleKeyserverEndpoint; type CallKeyserverEndpointContextType = { +createCallSingleKeyserverEndpointSelector: CreateCallSingleKeyserverEndpointSelector, + +getCallSingleKeyserverEndpoint: GetCallSingleKeyserverEndpoint, }; const CallKeyserverEndpointContext: React.Context = @@ -55,6 +61,8 @@ +children: React.Node, }; function CallKeyserverEndpointProvider(props: Props): React.Node { + // SECTION 1: bindCookieAndUtilsIntoCallServerEndpoint + const ongoingRecoveryAttemptsRef = React.useRef< Map, >(new Map()); @@ -189,6 +197,8 @@ ); }, []); + // SECTION 2: createCallSingleKeyserverEndpointSelector + // For each keyserver, we have a set of params that configure our connection // to it. These params get bound into callSingleKeyserverEndpoint before it's // passed to an ActionFunc. This helper function lets us create a selector for @@ -231,11 +241,52 @@ [bindCookieAndUtilsIntoCallSingleKeyserverEndpoint], ); + // SECTION 3: getCallSingleKeyserverEndpoint + + const dispatch = useDispatch(); + const currentUserInfo = useSelector(state => state.currentUserInfo); + + const keyserverInfos = useSelector( + state => state.keyserverStore.keyserverInfos, + ); + const keyserverCallInfos = useKeyserverCallInfos(keyserverInfos); + + const callSingleKeyserverEndpointSelectorCacheRef = React.useRef< + Map CallSingleKeyserverEndpoint>, + >(new Map()); + const getCallSingleKeyserverEndpoint: GetCallSingleKeyserverEndpoint = + React.useCallback( + (keyserverID: string) => { + let selector = + callSingleKeyserverEndpointSelectorCacheRef.current.get(keyserverID); + if (!selector) { + selector = createCallSingleKeyserverEndpointSelector(keyserverID); + callSingleKeyserverEndpointSelectorCacheRef.current.set( + keyserverID, + selector, + ); + } + const keyserverCallInfo = keyserverCallInfos[keyserverID]; + return selector({ + ...keyserverCallInfo, + dispatch, + currentUserInfo, + }); + }, + [ + createCallSingleKeyserverEndpointSelector, + dispatch, + currentUserInfo, + keyserverCallInfos, + ], + ); + const value = React.useMemo( () => ({ createCallSingleKeyserverEndpointSelector, + getCallSingleKeyserverEndpoint, }), - [createCallSingleKeyserverEndpointSelector], + [createCallSingleKeyserverEndpointSelector, getCallSingleKeyserverEndpoint], ); return (