Added loops to state across stores

This commit is contained in:
Emir Karabeg
2025-02-10 15:44:47 -08:00
parent 100e711023
commit a0b26120b8
4 changed files with 62 additions and 16 deletions

View File

@@ -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,

View File

@@ -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,
})
)

View File

@@ -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 },
}))
},
})),

View File

@@ -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 {