Line data Source code
1 : import * as React from 'react';
2 : import { ComputationAction, ComputationState, createComputationState, reduceComputationState } from "./computation_state.js";
3 : import { Dispatch } from '../utils/variant.js';
4 : import { Store, useStore, useStoreState } from '../utils/store.js';
5 : import { useLogger } from '../platform/logger/logger_provider.js';
6 : import { DataFrameRegistry } from './data_frame.js';
7 :
8 : // The state changes with every computation task step while dispatch and the data frame registry are stable.
9 : // Keep them in separate contexts so that consumers that only dispatch don't re-render on every step.
10 1 : const COMPUTATION_STATE_CTX = React.createContext<ComputationState | null>(null);
11 1 : const COMPUTATION_DISPATCH_CTX = React.createContext<Dispatch<ComputationAction> | null>(null);
12 1 : const DATA_FRAME_REGISTRY_CTX = React.createContext<DataFrameRegistry | null>(null);
13 1 : const COMPUTATION_STORE_CTX = React.createContext<Store<ComputationState> | null>(null);
14 :
15 1 : export const useComputationRegistry = (): [ComputationState, Dispatch<ComputationAction>, DataFrameRegistry] => [
16 1 : React.useContext(COMPUTATION_STATE_CTX)!,
17 1 : React.useContext(COMPUTATION_DISPATCH_CTX)!,
18 1 : React.useContext(DATA_FRAME_REGISTRY_CTX)!,
19 1 : ];
20 1 : export const useComputationDispatch = () => React.useContext(COMPUTATION_DISPATCH_CTX)!;
21 1 : export const useDataFrameRegistry = () => React.useContext(DATA_FRAME_REGISTRY_CTX)!;
22 : /// Get the computation state without subscribing to its changes
23 1 : export const useComputationStore = () => React.useContext(COMPUTATION_STORE_CTX)!;
24 :
25 : interface ComputationRegistryProps {
26 : children: React.ReactElement[] | React.ReactElement;
27 : }
28 :
29 1 : export function ComputationRegistry(props: ComputationRegistryProps) {
30 1 : const logger = useLogger();
31 1 : const dataFrameMemory = React.useMemo(() => new DataFrameRegistry(logger), []);
32 : // Reducing acquires and releases data frames, the store runs every action once
33 1 : const store = useStore<ComputationState>(createComputationState);
34 1 : const state = useStoreState(store);
35 1 : const dispatch = React.useCallback((action: ComputationAction) => {
36 1 : store.update(state => reduceComputationState(state, action, dataFrameMemory));
37 1 : }, [store, dataFrameMemory]);
38 1 : return (
39 1 : <DATA_FRAME_REGISTRY_CTX.Provider value={dataFrameMemory}>
40 1 : <COMPUTATION_STORE_CTX.Provider value={store}>
41 1 : <COMPUTATION_DISPATCH_CTX.Provider value={dispatch}>
42 1 : <COMPUTATION_STATE_CTX.Provider value={state}>
43 1 : {props.children}
44 1 : </COMPUTATION_STATE_CTX.Provider>
45 1 : </COMPUTATION_DISPATCH_CTX.Provider>
46 1 : </COMPUTATION_STORE_CTX.Provider>
47 1 : </DATA_FRAME_REGISTRY_CTX.Provider>
48 : );
49 1 : }
|