Flow Studio
Persistence — Save and Load
workflowStore serializes the canvas graph to JSON and saves it to the server via the process definition API. Auto-save fires on every tracked mutation. Load restores nodes, edges, and viewport from the saved payload.
serializeWorkflow
serializeWorkflow: () => SerializedWorkflow
// Returns a plain JSON-serializable representation of the current canvas state
const serialized = useWorkflowStore.getState().serializeWorkflow();
// Output shape:
interface SerializedWorkflow {
processId : string;
viewport : Viewport;
nodes : SerializedNode[];
edges : SerializedEdge[];
}
// Example output:
{
"processId": "proc-001",
"viewport" : { "x": -120, "y": 80, "zoom": 0.85 },
"nodes" : [
{ "id": "node-abc", "type": "ApprovalNode", "position": { "x": 400, "y": 200 },
"data": { "label": "Manager Approval", "config": { "actorId": "{{$context.managerId}}" },
"inputPorts": [...], "outputPorts": [...] } }
],
"edges" : [
{ "id": "edge-001", "source": "node-trigger", "sourceHandle": "out",
"target": "node-abc", "targetHandle": "in" }
]
}
deserializeWorkflow
deserializeWorkflow: (payload: SerializedWorkflow) => void
// Replaces the entire store state with the deserialized payload
// Called when loading an existing workflow from the API
useWorkflowStore.getState().deserializeWorkflow(apiResponse.definition);
// Internally calls:
// set({ nodes: payload.nodes, edges: payload.edges, viewport: payload.viewport,
// processId: payload.processId, selectedNodes: [], selectedEdges: [] })
// Then triggers React Flow to update its internal state
Auto-Save
// Persistence middleware wraps the store and intercepts tracked mutations
// Every call to addNode, updateNode, removeNode, moveNode, addEdge, removeEdge
// triggers a debounced saveWorkflow call
// Debounce window: 1500ms (configurable via AUTOSAVE_DEBOUNCE_MS)
// If 3 rapid mutations happen, only 1 save is made (1500ms after the last mutation)
// The save indicator in the toolbar shows:
// "Saving..." — save in progress
// "Saved" — last save succeeded
// "Unsaved changes" — save pending or failed
loadWorkflow
loadWorkflow: (processId: string) => Promise<void>
// Usage — called when the designer opens a specific workflow
const { loadWorkflow } = useWorkflowStore.getState();
await loadWorkflow('proc-001');
// Internally:
// 1. GET /api/processes/{processId}/definition
// 2. Calls deserializeWorkflow(response.definition)
// 3. Resets the undo/redo history stack (fresh load = no history)
Save API Endpoint
// PUT /api/processes/{processId}/definition
// Body: SerializedWorkflow JSON
// Response: { savedAt: "2026-05-25T10:00:00Z", version: 42 }
Auto-save saves the canvas graph only — not execution results, pinned data, or run history. Those are managed by the ProcessEngine backend and are never overwritten by the designer save operation.