| 
									
										
										
										
											2024-06-26 08:37:12 +02:00
										 |  |  | import { type ReactNode, createContext, useContext, useMemo, useState } from 'react' | 
					
						
							|  |  |  | import { type StoreApi, create } from 'zustand' | 
					
						
							|  |  |  | import { type TemporalState, temporal } from 'zundo' | 
					
						
							|  |  |  | import isDeepEqual from 'fast-deep-equal' | 
					
						
							|  |  |  | import type { Edge, Node } from './types' | 
					
						
							|  |  |  | import type { WorkflowHistoryEvent } from './hooks' | 
					
						
							| 
									
										
										
										
											2025-04-06 17:56:08 +08:00
										 |  |  | import { noop } from 'lodash-es' | 
					
						
							| 
									
										
										
										
											2024-06-26 08:37:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-06 17:56:08 +08:00
										 |  |  | export const WorkflowHistoryStoreContext = createContext<WorkflowHistoryStoreContextType>({ store: null, shortcutsEnabled: true, setShortcutsEnabled: noop }) | 
					
						
							| 
									
										
										
										
											2024-06-26 08:37:12 +02:00
										 |  |  | export const Provider = WorkflowHistoryStoreContext.Provider | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function WorkflowHistoryProvider({ | 
					
						
							|  |  |  |   nodes, | 
					
						
							|  |  |  |   edges, | 
					
						
							|  |  |  |   children, | 
					
						
							|  |  |  | }: WorkflowWithHistoryProviderProps) { | 
					
						
							|  |  |  |   const [shortcutsEnabled, setShortcutsEnabled] = useState(true) | 
					
						
							|  |  |  |   const [store] = useState(() => | 
					
						
							|  |  |  |     createStore({ | 
					
						
							|  |  |  |       nodes, | 
					
						
							|  |  |  |       edges, | 
					
						
							|  |  |  |     }), | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const contextValue = { | 
					
						
							|  |  |  |     store, | 
					
						
							|  |  |  |     shortcutsEnabled, | 
					
						
							|  |  |  |     setShortcutsEnabled, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     <Provider value={contextValue}> | 
					
						
							|  |  |  |       {children} | 
					
						
							|  |  |  |     </Provider> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function useWorkflowHistoryStore() { | 
					
						
							|  |  |  |   const { | 
					
						
							|  |  |  |     store, | 
					
						
							|  |  |  |     shortcutsEnabled, | 
					
						
							|  |  |  |     setShortcutsEnabled, | 
					
						
							|  |  |  |   } = useContext(WorkflowHistoryStoreContext) | 
					
						
							|  |  |  |   if (store === null) | 
					
						
							|  |  |  |     throw new Error('useWorkflowHistoryStoreApi must be used within a WorkflowHistoryProvider') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     store: useMemo( | 
					
						
							|  |  |  |       () => ({ | 
					
						
							|  |  |  |         getState: store.getState, | 
					
						
							|  |  |  |         setState: (state: WorkflowHistoryState) => { | 
					
						
							|  |  |  |           store.setState({ | 
					
						
							|  |  |  |             workflowHistoryEvent: state.workflowHistoryEvent, | 
					
						
							|  |  |  |             nodes: state.nodes.map((node: Node) => ({ ...node, data: { ...node.data, selected: false } })), | 
					
						
							|  |  |  |             edges: state.edges.map((edge: Edge) => ({ ...edge, selected: false }) as Edge), | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         subscribe: store.subscribe, | 
					
						
							|  |  |  |         temporal: store.temporal, | 
					
						
							|  |  |  |       }), | 
					
						
							|  |  |  |       [store], | 
					
						
							|  |  |  |     ), | 
					
						
							|  |  |  |     shortcutsEnabled, | 
					
						
							|  |  |  |     setShortcutsEnabled, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function createStore({ | 
					
						
							|  |  |  |   nodes: storeNodes, | 
					
						
							|  |  |  |   edges: storeEdges, | 
					
						
							|  |  |  | }: { | 
					
						
							|  |  |  |   nodes: Node[] | 
					
						
							|  |  |  |   edges: Edge[] | 
					
						
							|  |  |  | }): WorkflowHistoryStoreApi { | 
					
						
							|  |  |  |   const store = create(temporal<WorkflowHistoryState>( | 
					
						
							|  |  |  |     (set, get) => { | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         workflowHistoryEvent: undefined, | 
					
						
							|  |  |  |         nodes: storeNodes, | 
					
						
							|  |  |  |         edges: storeEdges, | 
					
						
							|  |  |  |         getNodes: () => get().nodes, | 
					
						
							|  |  |  |         setNodes: (nodes: Node[]) => set({ nodes }), | 
					
						
							|  |  |  |         setEdges: (edges: Edge[]) => set({ edges }), | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       equality: (pastState, currentState) => | 
					
						
							|  |  |  |         isDeepEqual(pastState, currentState), | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   ), | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return store | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export type WorkflowHistoryStore = { | 
					
						
							|  |  |  |   nodes: Node[] | 
					
						
							|  |  |  |   edges: Edge[] | 
					
						
							|  |  |  |   workflowHistoryEvent: WorkflowHistoryEvent | undefined | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export type WorkflowHistoryActions = { | 
					
						
							|  |  |  |   setNodes?: (nodes: Node[]) => void | 
					
						
							|  |  |  |   setEdges?: (edges: Edge[]) => void | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export type WorkflowHistoryState = WorkflowHistoryStore & WorkflowHistoryActions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type WorkflowHistoryStoreContextType = { | 
					
						
							|  |  |  |   store: ReturnType<typeof createStore> | null | 
					
						
							|  |  |  |   shortcutsEnabled: boolean | 
					
						
							|  |  |  |   setShortcutsEnabled: (enabled: boolean) => void | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export type WorkflowHistoryStoreApi = StoreApi<WorkflowHistoryState> & { temporal: StoreApi<TemporalState<WorkflowHistoryState>> } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export type WorkflowWithHistoryProviderProps = { | 
					
						
							|  |  |  |   nodes: Node[] | 
					
						
							|  |  |  |   edges: Edge[] | 
					
						
							|  |  |  |   children: ReactNode | 
					
						
							|  |  |  | } |