MCPcopy
hub / github.com/simstudioai/sim / saveWorkflowToNormalizedTables

Function saveWorkflowToNormalizedTables

packages/workflow-persistence/src/save.ts:15–108  ·  view source on GitHub ↗
(
  workflowId: string,
  state: WorkflowState,
  externalTx?: DbOrTx
)

Source from the content-addressed store, hash-verified

13type SubflowInsert = InferInsertModel<typeof workflowSubflows>
14
15export async function saveWorkflowToNormalizedTables(
16 workflowId: string,
17 state: WorkflowState,
18 externalTx?: DbOrTx
19): Promise<{ success: boolean; error?: string }> {
20 const blockRecords = state.blocks as Record<string, BlockState>
21 const canonicalLoops = generateLoopBlocks(blockRecords)
22 const canonicalParallels = generateParallelBlocks(blockRecords)
23
24 const execute = async (tx: DbOrTx) => {
25 await Promise.all([
26 tx.delete(workflowBlocks).where(eq(workflowBlocks.workflowId, workflowId)),
27 tx.delete(workflowEdges).where(eq(workflowEdges.workflowId, workflowId)),
28 tx.delete(workflowSubflows).where(eq(workflowSubflows.workflowId, workflowId)),
29 ])
30
31 if (Object.keys(state.blocks).length > 0) {
32 const blockInserts = Object.values(state.blocks).map((block) => ({
33 id: block.id,
34 workflowId,
35 type: block.type,
36 name: block.name || '',
37 positionX: String(block.position?.x || 0),
38 positionY: String(block.position?.y || 0),
39 enabled: block.enabled ?? true,
40 horizontalHandles: block.horizontalHandles ?? true,
41 advancedMode: block.advancedMode ?? false,
42 triggerMode: block.triggerMode ?? false,
43 height: String(block.height || 0),
44 subBlocks: block.subBlocks || {},
45 outputs: block.outputs || {},
46 data: block.data || {},
47 parentId: block.data?.parentId || null,
48 extent: block.data?.extent || null,
49 locked: block.locked ?? false,
50 }))
51
52 await tx.insert(workflowBlocks).values(blockInserts)
53 }
54
55 if (state.edges.length > 0) {
56 const edgeInserts = state.edges.map((edge) => ({
57 id: edge.id,
58 workflowId,
59 sourceBlockId: edge.source,
60 targetBlockId: edge.target,
61 sourceHandle: edge.sourceHandle || null,
62 targetHandle: edge.targetHandle || null,
63 }))
64
65 await tx.insert(workflowEdges).values(edgeInserts)
66 }
67
68 const subflowInserts: SubflowInsert[] = []
69
70 Object.values(canonicalLoops).forEach((loop) => {
71 subflowInserts.push({
72 id: loop.id,

Callers

nothing calls this directly

Calls 5

generateLoopBlocksFunction · 0.90
generateParallelBlocksFunction · 0.90
toErrorFunction · 0.90
errorMethod · 0.80
executeFunction · 0.70

Tested by

no test coverage detected