diff --git a/lib/components/ops-context-provider.react.js b/lib/components/ops-context-provider.react.js --- a/lib/components/ops-context-provider.react.js +++ b/lib/components/ops-context-provider.react.js @@ -1,10 +1,12 @@ // @flow import * as React from 'react'; +import uuid from 'uuid'; import { OpsContext } from './ops-context.js'; +import type { ActionID } from '../types/db-ops-types.js'; import type { SuperAction } from '../types/redux-types.js'; -import { useDispatch } from '../utils/redux-utils.js'; +import { useDispatch, useSelector } from '../utils/redux-utils.js'; type Props = { +children: React.Node, @@ -13,15 +15,41 @@ function OpsContextProvider(props: Props): React.Node { const { children } = props; + const actionsToPromises = React.useRef mixed>>(new Map()); + const dispatch = useDispatch(); const dispatchWrapper = React.useCallback( (action: SuperAction) => { - dispatch(action); - return Promise.resolve(); + const actionID = uuid.v4(); + dispatch({ + ...action, + actionID, + }); + return new Promise(resolve => + actionsToPromises.current.set(actionID, resolve), + ); }, [dispatch], ); + const { noOpsActions, queuedOps } = useSelector(state => state.dbOpsStore); + const prevActionIDs = React.useRef<$ReadOnlySet>(new Set()); + React.useEffect(() => { + const newActionIDs = new Set(noOpsActions); + for (const ops of queuedOps) { + if (ops.actionID) { + newActionIDs.add(ops.actionID); + } + } + for (const id of prevActionIDs.current) { + if (!newActionIDs.has(id)) { + actionsToPromises.current.get(id)?.(); + actionsToPromises.current.delete(id); + } + } + prevActionIDs.current = newActionIDs; + }, [noOpsActions, queuedOps]); + const contextValue = React.useMemo( () => ({ dispatch: dispatchWrapper }), [dispatchWrapper],