mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 15:07:55 -05:00
217 lines
6.4 KiB
TypeScript
217 lines
6.4 KiB
TypeScript
import { create } from 'zustand'
|
|
import { devtools } from 'zustand/middleware'
|
|
import { WorkflowRegistry, WorkflowMetadata } from './registry-types'
|
|
import { useWorkflowStore } from './store'
|
|
|
|
export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
|
devtools(
|
|
(set, get) => ({
|
|
workflows: {},
|
|
activeWorkflowId: null,
|
|
isLoading: false,
|
|
error: null,
|
|
|
|
setActiveWorkflow: async (id: string) => {
|
|
const { workflows } = get()
|
|
if (!workflows[id]) {
|
|
set({ error: `Workflow ${id} not found` })
|
|
return
|
|
}
|
|
|
|
// Save current workflow state before switching
|
|
const currentId = get().activeWorkflowId
|
|
if (currentId) {
|
|
const currentState = useWorkflowStore.getState()
|
|
localStorage.setItem(`workflow-${currentId}`, JSON.stringify({
|
|
blocks: currentState.blocks,
|
|
edges: currentState.edges,
|
|
history: currentState.history // Save history state
|
|
}))
|
|
}
|
|
|
|
// Load new workflow state
|
|
const savedState = localStorage.getItem(`workflow-${id}`)
|
|
if (savedState) {
|
|
const { blocks, edges, history } = JSON.parse(savedState)
|
|
useWorkflowStore.setState({
|
|
blocks,
|
|
edges,
|
|
history: history || {
|
|
past: [],
|
|
present: {
|
|
state: { blocks, edges },
|
|
timestamp: Date.now(),
|
|
action: 'Initial state'
|
|
},
|
|
future: []
|
|
}
|
|
})
|
|
} else {
|
|
useWorkflowStore.setState({
|
|
blocks: {},
|
|
edges: [],
|
|
history: {
|
|
past: [],
|
|
present: {
|
|
state: { blocks: {}, edges: [] },
|
|
timestamp: Date.now(),
|
|
action: 'Initial state'
|
|
},
|
|
future: []
|
|
},
|
|
lastSaved: Date.now()
|
|
})
|
|
}
|
|
|
|
set({ activeWorkflowId: id, error: null })
|
|
},
|
|
|
|
addWorkflow: (metadata: WorkflowMetadata) => {
|
|
const uniqueName = generateUniqueName(get().workflows)
|
|
const updatedMetadata = { ...metadata, name: uniqueName }
|
|
|
|
set((state) => ({
|
|
workflows: {
|
|
...state.workflows,
|
|
[metadata.id]: updatedMetadata
|
|
},
|
|
error: null
|
|
}))
|
|
|
|
// Save workflow list to localStorage
|
|
const workflows = get().workflows
|
|
localStorage.setItem('workflow-registry', JSON.stringify(workflows))
|
|
},
|
|
|
|
removeWorkflow: (id: string) => {
|
|
set((state) => {
|
|
const newWorkflows = { ...state.workflows }
|
|
delete newWorkflows[id]
|
|
|
|
// Remove workflow state from localStorage
|
|
localStorage.removeItem(`workflow-${id}`)
|
|
|
|
// Update registry in localStorage
|
|
localStorage.setItem('workflow-registry', JSON.stringify(newWorkflows))
|
|
|
|
// If deleting active workflow, switch to another one
|
|
let newActiveWorkflowId = state.activeWorkflowId
|
|
if (state.activeWorkflowId === id) {
|
|
const remainingIds = Object.keys(newWorkflows)
|
|
// Switch to first available workflow
|
|
newActiveWorkflowId = remainingIds[0]
|
|
const savedState = localStorage.getItem(`workflow-${newActiveWorkflowId}`)
|
|
if (savedState) {
|
|
const { blocks, edges, history } = JSON.parse(savedState)
|
|
useWorkflowStore.setState({
|
|
blocks,
|
|
edges,
|
|
history: history || {
|
|
past: [],
|
|
present: {
|
|
state: { blocks, edges },
|
|
timestamp: Date.now(),
|
|
action: 'Initial state'
|
|
},
|
|
future: []
|
|
}
|
|
})
|
|
} else {
|
|
useWorkflowStore.setState({
|
|
blocks: {},
|
|
edges: [],
|
|
history: {
|
|
past: [],
|
|
present: {
|
|
state: { blocks: {}, edges: [] },
|
|
timestamp: Date.now(),
|
|
action: 'Initial state'
|
|
},
|
|
future: []
|
|
},
|
|
lastSaved: Date.now()
|
|
})
|
|
}
|
|
}
|
|
|
|
return {
|
|
workflows: newWorkflows,
|
|
activeWorkflowId: newActiveWorkflowId,
|
|
error: null
|
|
}
|
|
})
|
|
},
|
|
|
|
updateWorkflow: (id: string, metadata: Partial<WorkflowMetadata>) => {
|
|
set((state) => {
|
|
const workflow = state.workflows[id]
|
|
if (!workflow) return state
|
|
|
|
const updatedWorkflows = {
|
|
...state.workflows,
|
|
[id]: {
|
|
...workflow,
|
|
...metadata,
|
|
lastModified: new Date()
|
|
}
|
|
}
|
|
|
|
// Update registry in localStorage
|
|
localStorage.setItem('workflow-registry', JSON.stringify(updatedWorkflows))
|
|
|
|
return {
|
|
workflows: updatedWorkflows,
|
|
error: null
|
|
}
|
|
})
|
|
}
|
|
}),
|
|
{ name: 'workflow-registry' }
|
|
)
|
|
)
|
|
|
|
const generateUniqueName = (existingWorkflows: Record<string, WorkflowMetadata>): string => {
|
|
// Extract numbers from existing workflow names using regex
|
|
const numbers = Object.values(existingWorkflows)
|
|
.map(w => {
|
|
const match = w.name.match(/Workflow (\d+)/)
|
|
return match ? parseInt(match[1]) : 0
|
|
})
|
|
.filter(n => n > 0)
|
|
|
|
if (numbers.length === 0) {
|
|
return 'Workflow 1'
|
|
}
|
|
|
|
// Find the maximum number and add 1
|
|
const nextNumber = Math.max(...numbers) + 1
|
|
return `Workflow ${nextNumber}`
|
|
}
|
|
|
|
// Initialize registry from localStorage
|
|
const initializeRegistry = () => {
|
|
const savedRegistry = localStorage.getItem('workflow-registry')
|
|
if (savedRegistry) {
|
|
const workflows = JSON.parse(savedRegistry)
|
|
useWorkflowRegistry.setState({ workflows })
|
|
}
|
|
|
|
// Add event listeners for page unload
|
|
window.addEventListener('beforeunload', () => {
|
|
// Save current workflow state
|
|
const currentId = useWorkflowRegistry.getState().activeWorkflowId
|
|
if (currentId) {
|
|
const currentState = useWorkflowStore.getState()
|
|
localStorage.setItem(`workflow-${currentId}`, JSON.stringify({
|
|
blocks: currentState.blocks,
|
|
edges: currentState.edges,
|
|
history: currentState.history
|
|
}))
|
|
}
|
|
})
|
|
}
|
|
|
|
if (typeof window !== 'undefined') {
|
|
initializeRegistry()
|
|
}
|