feat(ui): extract node execution state from nodesSlice

This state is ephemeral and not undoable.
This commit is contained in:
psychedelicious
2024-05-17 13:21:01 +10:00
parent d2f5103f9f
commit ad8778df6c
12 changed files with 141 additions and 128 deletions

View File

@ -0,0 +1,56 @@
import { useStore } from '@nanostores/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppSelector } from 'app/store/storeHooks';
import { deepClone } from 'common/util/deepClone';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import type { NodeExecutionStates } from 'features/nodes/store/types';
import type { NodeExecutionState } from 'features/nodes/types/invocation';
import { zNodeStatus } from 'features/nodes/types/invocation';
import { map } from 'nanostores';
import { useEffect, useMemo } from 'react';
export const $nodeExecutionStates = map<NodeExecutionStates>({});
const initialNodeExecutionState: Omit<NodeExecutionState, 'nodeId'> = {
status: zNodeStatus.enum.PENDING,
error: null,
progress: null,
progressImage: null,
outputs: [],
};
export const useExecutionState = (nodeId?: string) => {
const executionStates = useStore($nodeExecutionStates, nodeId ? { keys: [nodeId] } : undefined);
const executionState = useMemo(() => (nodeId ? executionStates[nodeId] : undefined), [executionStates, nodeId]);
return executionState;
};
const removeNodeExecutionState = (nodeId: string) => {
$nodeExecutionStates.setKey(nodeId, undefined);
};
export const upsertExecutionState = (nodeId: string, updates?: Partial<NodeExecutionState>) => {
const state = $nodeExecutionStates.get()[nodeId];
if (!state) {
$nodeExecutionStates.setKey(nodeId, { ...deepClone(initialNodeExecutionState), nodeId, ...updates });
} else {
$nodeExecutionStates.setKey(nodeId, { ...state, ...updates });
}
};
const selectNodeIds = createMemoizedSelector(selectNodesSlice, (nodesSlice) => nodesSlice.nodes.map((node) => node.id));
export const useSyncExecutionState = () => {
const nodeIds = useAppSelector(selectNodeIds);
useEffect(() => {
const nodeExecutionStates = $nodeExecutionStates.get();
const nodeIdsToAdd = nodeIds.filter((id) => !nodeExecutionStates[id]);
const nodeIdsToRemove = Object.keys(nodeExecutionStates).filter((id) => !nodeIds.includes(id));
for (const id of nodeIdsToAdd) {
upsertExecutionState(id);
}
for (const id of nodeIdsToRemove) {
removeNodeExecutionState(id);
}
}, [nodeIds]);
};