mirror of
https://github.com/langgenius/dify.git
synced 2024-11-16 19:59:50 +08:00
121 lines
3.1 KiB
TypeScript
121 lines
3.1 KiB
TypeScript
|
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'
|
||
|
|
||
|
export const WorkflowHistoryStoreContext = createContext<WorkflowHistoryStoreContextType>({ store: null, shortcutsEnabled: true, setShortcutsEnabled: () => {} })
|
||
|
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
|
||
|
}
|