mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 15:07:55 -05:00
Added loops to state across stores
This commit is contained in:
@@ -17,6 +17,7 @@ export const withHistory = (
|
||||
state: {
|
||||
blocks: initialState.blocks,
|
||||
edges: initialState.edges,
|
||||
loops: initialState.loops,
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
action: 'Initial state',
|
||||
@@ -73,10 +74,11 @@ export const withHistory = (
|
||||
const newState = {
|
||||
blocks: {},
|
||||
edges: [],
|
||||
loops: {},
|
||||
history: {
|
||||
past: [],
|
||||
present: {
|
||||
state: { blocks: {}, edges: [] },
|
||||
state: { blocks: {}, edges: [], loops: {} },
|
||||
timestamp: Date.now(),
|
||||
action: 'Clear workflow',
|
||||
},
|
||||
@@ -115,6 +117,7 @@ export const createHistoryEntry = (state: WorkflowState, action: string): Histor
|
||||
state: {
|
||||
blocks: { ...state.blocks },
|
||||
edges: [...state.edges],
|
||||
loops: { ...state.loops },
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
action,
|
||||
|
||||
@@ -27,7 +27,8 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
||||
JSON.stringify({
|
||||
blocks: currentState.blocks,
|
||||
edges: currentState.edges,
|
||||
history: currentState.history, // Save history state
|
||||
loops: currentState.loops,
|
||||
history: currentState.history,
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -35,14 +36,15 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
||||
// Load new workflow state
|
||||
const savedState = localStorage.getItem(`workflow-${id}`)
|
||||
if (savedState) {
|
||||
const { blocks, edges, history } = JSON.parse(savedState)
|
||||
const { blocks, edges, history, loops } = JSON.parse(savedState)
|
||||
useWorkflowStore.setState({
|
||||
blocks,
|
||||
edges,
|
||||
loops: loops || {},
|
||||
history: history || {
|
||||
past: [],
|
||||
present: {
|
||||
state: { blocks, edges },
|
||||
state: { blocks, edges, loops: {} },
|
||||
timestamp: Date.now(),
|
||||
action: 'Initial state',
|
||||
},
|
||||
@@ -53,10 +55,11 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
||||
useWorkflowStore.setState({
|
||||
blocks: {},
|
||||
edges: [],
|
||||
loops: {},
|
||||
history: {
|
||||
past: [],
|
||||
present: {
|
||||
state: { blocks: {}, edges: [] },
|
||||
state: { blocks: {}, edges: [], loops: {} },
|
||||
timestamp: Date.now(),
|
||||
action: 'Initial state',
|
||||
},
|
||||
@@ -123,10 +126,11 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
||||
useWorkflowStore.setState({
|
||||
blocks: {},
|
||||
edges: [],
|
||||
loops: {},
|
||||
history: {
|
||||
past: [],
|
||||
present: {
|
||||
state: { blocks: {}, edges: [] },
|
||||
state: { blocks: {}, edges: [], loops: {} },
|
||||
timestamp: Date.now(),
|
||||
action: 'Initial state',
|
||||
},
|
||||
@@ -201,7 +205,6 @@ const initializeRegistry = () => {
|
||||
|
||||
// Add event listeners for page unload
|
||||
window.addEventListener('beforeunload', () => {
|
||||
// Save current workflow state
|
||||
const currentId = useWorkflowRegistry.getState().activeWorkflowId
|
||||
if (currentId) {
|
||||
const currentState = useWorkflowStore.getState()
|
||||
@@ -210,6 +213,7 @@ const initializeRegistry = () => {
|
||||
JSON.stringify({
|
||||
blocks: currentState.blocks,
|
||||
edges: currentState.edges,
|
||||
loops: currentState.loops,
|
||||
history: currentState.history,
|
||||
})
|
||||
)
|
||||
|
||||
@@ -4,17 +4,18 @@ import { devtools } from 'zustand/middleware'
|
||||
import { getBlock } from '@/blocks'
|
||||
import { resolveOutputType } from '@/blocks/utils'
|
||||
import { WorkflowStoreWithHistory, pushHistory, withHistory } from './middleware'
|
||||
import { Position, SubBlockState } from './types'
|
||||
import { Position, SubBlockState, Loop } from './types'
|
||||
import { detectCycle } from './utils'
|
||||
|
||||
const initialState = {
|
||||
blocks: {},
|
||||
edges: [],
|
||||
loops: {},
|
||||
lastSaved: undefined,
|
||||
history: {
|
||||
past: [],
|
||||
present: {
|
||||
state: { blocks: {}, edges: [] },
|
||||
state: { blocks: {}, edges: [], loops: {} },
|
||||
timestamp: Date.now(),
|
||||
action: 'Initial state',
|
||||
},
|
||||
@@ -146,6 +147,7 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
},
|
||||
},
|
||||
edges: [...get().edges],
|
||||
loops: { ...get().loops },
|
||||
}
|
||||
|
||||
set(newState)
|
||||
@@ -171,6 +173,7 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
const newState = {
|
||||
blocks: { ...get().blocks },
|
||||
edges: [...get().edges].filter((edge) => edge.source !== id && edge.target !== id),
|
||||
loops: { ...get().loops },
|
||||
}
|
||||
delete newState.blocks[id]
|
||||
|
||||
@@ -180,7 +183,6 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
},
|
||||
|
||||
addEdge: (edge: Edge) => {
|
||||
// First create the new edge
|
||||
const newEdge = {
|
||||
id: edge.id || crypto.randomUUID(),
|
||||
source: edge.source,
|
||||
@@ -189,19 +191,24 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
targetHandle: edge.targetHandle,
|
||||
}
|
||||
|
||||
// Create temporary edges array with the new edge
|
||||
const newEdges = [...get().edges, newEdge]
|
||||
|
||||
// Check for cycles starting from the source node
|
||||
const { hasCycle, path } = detectCycle(newEdges, edge.source)
|
||||
|
||||
// Create new loops state
|
||||
const newLoops = { ...get().loops }
|
||||
|
||||
if (hasCycle) {
|
||||
console.log('Loop detected through nodes:', path.join(' → '))
|
||||
const loopId = crypto.randomUUID()
|
||||
newLoops[loopId] = {
|
||||
id: loopId,
|
||||
nodes: path
|
||||
}
|
||||
}
|
||||
|
||||
const newState = {
|
||||
blocks: { ...get().blocks },
|
||||
edges: newEdges,
|
||||
loops: newLoops,
|
||||
}
|
||||
|
||||
set(newState)
|
||||
@@ -210,9 +217,31 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
},
|
||||
|
||||
removeEdge: (edgeId: string) => {
|
||||
const newEdges = get().edges.filter((edge) => edge.id !== edgeId)
|
||||
|
||||
// Recalculate loops after edge removal
|
||||
const newLoops: Record<string, Loop> = {}
|
||||
const processedNodes = new Set<string>()
|
||||
|
||||
// Check for cycles from each source node
|
||||
newEdges.forEach(edge => {
|
||||
if (!processedNodes.has(edge.source)) {
|
||||
const { hasCycle, path } = detectCycle(newEdges, edge.source)
|
||||
if (hasCycle) {
|
||||
const loopId = crypto.randomUUID()
|
||||
newLoops[loopId] = {
|
||||
id: loopId,
|
||||
nodes: path
|
||||
}
|
||||
}
|
||||
processedNodes.add(edge.source)
|
||||
}
|
||||
})
|
||||
|
||||
const newState = {
|
||||
blocks: { ...get().blocks },
|
||||
edges: get().edges.filter((edge) => edge.id !== edgeId),
|
||||
edges: newEdges,
|
||||
loops: newLoops,
|
||||
}
|
||||
|
||||
set(newState)
|
||||
@@ -224,10 +253,11 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
const newState = {
|
||||
blocks: {},
|
||||
edges: [],
|
||||
loops: {},
|
||||
history: {
|
||||
past: [],
|
||||
present: {
|
||||
state: { blocks: {}, edges: [] },
|
||||
state: { blocks: {}, edges: [], loops: {} },
|
||||
timestamp: Date.now(),
|
||||
action: 'Initial state',
|
||||
},
|
||||
@@ -297,6 +327,7 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
},
|
||||
},
|
||||
edges: [...get().edges],
|
||||
loops: { ...get().loops },
|
||||
}
|
||||
|
||||
set(newState)
|
||||
@@ -330,6 +361,7 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
},
|
||||
},
|
||||
edges: [...get().edges],
|
||||
loops: { ...get().loops },
|
||||
}
|
||||
|
||||
set(newState)
|
||||
@@ -347,6 +379,7 @@ export const useWorkflowStore = create<WorkflowStoreWithHistory>()(
|
||||
},
|
||||
},
|
||||
edges: [...state.edges],
|
||||
loops: { ...get().loops },
|
||||
}))
|
||||
},
|
||||
})),
|
||||
|
||||
@@ -24,10 +24,16 @@ export interface SubBlockState {
|
||||
value: string | number | string[][] | null
|
||||
}
|
||||
|
||||
export interface Loop {
|
||||
id: string
|
||||
nodes: string[]
|
||||
}
|
||||
|
||||
export interface WorkflowState {
|
||||
blocks: Record<string, BlockState>
|
||||
edges: Edge[]
|
||||
lastSaved?: number
|
||||
loops: Record<string, Loop>
|
||||
}
|
||||
|
||||
export interface WorkflowActions {
|
||||
|
||||
Reference in New Issue
Block a user