flowcraft 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/analysis.d.ts +1 -1
  2. package/dist/{chunk-C4HYIJI3.js → chunk-7PBANEG3.js} +16 -2
  3. package/dist/chunk-7PBANEG3.js.map +1 -0
  4. package/dist/{chunk-IB2BISIC.js → chunk-CHG6O6JX.js} +38 -8
  5. package/dist/chunk-CHG6O6JX.js.map +1 -0
  6. package/dist/{chunk-XNRIM27H.js → chunk-GIJOZ3AN.js} +4 -4
  7. package/dist/{chunk-XNRIM27H.js.map → chunk-GIJOZ3AN.js.map} +1 -1
  8. package/dist/{chunk-CD3Q4N6V.js → chunk-GVF7GQXQ.js} +6 -3
  9. package/dist/chunk-GVF7GQXQ.js.map +1 -0
  10. package/dist/{chunk-6INWPSZT.js → chunk-J3HZD5ES.js} +45 -25
  11. package/dist/chunk-J3HZD5ES.js.map +1 -0
  12. package/dist/{chunk-5KKSQWSC.js → chunk-K6LPGUPR.js} +5 -5
  13. package/dist/chunk-K6LPGUPR.js.map +1 -0
  14. package/dist/{chunk-FRKO3WX4.js → chunk-KXXEA5VE.js} +3 -3
  15. package/dist/{chunk-FRKO3WX4.js.map → chunk-KXXEA5VE.js.map} +1 -1
  16. package/dist/chunk-LJ4COM7S.js +20 -0
  17. package/dist/chunk-LJ4COM7S.js.map +1 -0
  18. package/dist/chunk-LM4ACVHL.js +73 -0
  19. package/dist/chunk-LM4ACVHL.js.map +1 -0
  20. package/dist/{chunk-33NO4PUJ.js → chunk-NDWVLU7J.js} +3 -3
  21. package/dist/{chunk-33NO4PUJ.js.map → chunk-NDWVLU7J.js.map} +1 -1
  22. package/dist/{chunk-CD4FUZOJ.js → chunk-OO3FF3DF.js} +22 -8
  23. package/dist/chunk-OO3FF3DF.js.map +1 -0
  24. package/dist/{chunk-QNYXQKFW.js → chunk-OZZP5YI6.js} +3 -3
  25. package/dist/{chunk-QNYXQKFW.js.map → chunk-OZZP5YI6.js.map} +1 -1
  26. package/dist/{chunk-CY755I7I.js → chunk-VN2JKKAE.js} +3 -3
  27. package/dist/{chunk-CY755I7I.js.map → chunk-VN2JKKAE.js.map} +1 -1
  28. package/dist/container-factory.d.ts +1 -1
  29. package/dist/container-factory.js +4 -4
  30. package/dist/context.d.ts +1 -1
  31. package/dist/evaluator.d.ts +1 -1
  32. package/dist/flow.d.ts +10 -1
  33. package/dist/flow.js +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.js +13 -11
  36. package/dist/linter.d.ts +1 -1
  37. package/dist/logger.d.ts +1 -1
  38. package/dist/node.d.ts +1 -1
  39. package/dist/nodes/batch-gather.d.ts +1 -1
  40. package/dist/nodes/batch-scatter.d.ts +1 -1
  41. package/dist/nodes/sleep.d.ts +9 -0
  42. package/dist/nodes/sleep.js +4 -0
  43. package/dist/nodes/sleep.js.map +1 -0
  44. package/dist/nodes/subflow.d.ts +1 -1
  45. package/dist/nodes/subflow.js +3 -3
  46. package/dist/nodes/wait.d.ts +1 -1
  47. package/dist/nodes/wait.js +1 -1
  48. package/dist/runtime/adapter.d.ts +2 -1
  49. package/dist/runtime/adapter.js +11 -9
  50. package/dist/runtime/execution-context.d.ts +1 -1
  51. package/dist/runtime/execution-context.js +2 -2
  52. package/dist/runtime/executors.d.ts +1 -1
  53. package/dist/runtime/index.d.ts +1 -1
  54. package/dist/runtime/index.js +11 -9
  55. package/dist/runtime/node-executor-factory.d.ts +1 -1
  56. package/dist/runtime/orchestrator.d.ts +1 -1
  57. package/dist/runtime/orchestrator.js +3 -3
  58. package/dist/runtime/orchestrators/step-by-step.d.ts +1 -1
  59. package/dist/runtime/orchestrators/utils.d.ts +1 -1
  60. package/dist/runtime/runtime.d.ts +1 -1
  61. package/dist/runtime/runtime.js +10 -8
  62. package/dist/runtime/scheduler.d.ts +3 -0
  63. package/dist/runtime/scheduler.js +3 -0
  64. package/dist/runtime/scheduler.js.map +1 -0
  65. package/dist/runtime/state.d.ts +1 -1
  66. package/dist/runtime/state.js +1 -1
  67. package/dist/runtime/traverser.d.ts +1 -1
  68. package/dist/runtime/types.d.ts +1 -1
  69. package/dist/runtime/workflow-logic-handler.d.ts +1 -1
  70. package/dist/sanitizer.d.ts +1 -1
  71. package/dist/serializer.d.ts +1 -1
  72. package/dist/testing/event-logger.d.ts +1 -1
  73. package/dist/testing/index.d.ts +1 -1
  74. package/dist/testing/index.js +13 -11
  75. package/dist/testing/run-with-trace.d.ts +1 -1
  76. package/dist/testing/run-with-trace.js +12 -10
  77. package/dist/testing/stepper.d.ts +1 -1
  78. package/dist/testing/stepper.js +3 -3
  79. package/dist/{types-ezHUBdpL.d.ts → types-DWCZW68f.d.ts} +29 -2
  80. package/dist/types.d.ts +1 -1
  81. package/package.json +1 -1
  82. package/dist/chunk-5KKSQWSC.js.map +0 -1
  83. package/dist/chunk-6INWPSZT.js.map +0 -1
  84. package/dist/chunk-C4HYIJI3.js.map +0 -1
  85. package/dist/chunk-CD3Q4N6V.js.map +0 -1
  86. package/dist/chunk-CD4FUZOJ.js.map +0 -1
  87. package/dist/chunk-IB2BISIC.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { g as WorkflowBlueprint } from './types-ezHUBdpL.js';
1
+ import { g as WorkflowBlueprint } from './types-DWCZW68f.js';
2
2
  import './errors.js';
3
3
  import './container.js';
4
4
 
@@ -86,6 +86,20 @@ var Flow = class {
86
86
  this.edge(scatterId, gatherId);
87
87
  return this;
88
88
  }
89
+ /**
90
+ * Creates a sleep node that pauses workflow execution for a specified duration.
91
+ * @param id A unique identifier for the sleep node.
92
+ * @param options Configuration for the sleep duration.
93
+ */
94
+ sleep(id, options) {
95
+ const nodeDef = {
96
+ id,
97
+ uses: "sleep",
98
+ params: { duration: options.duration }
99
+ };
100
+ this.blueprint.nodes?.push(nodeDef);
101
+ return this;
102
+ }
89
103
  /**
90
104
  * Creates a wait node that pauses workflow execution for external input.
91
105
  * @param id A unique identifier for the wait node.
@@ -275,5 +289,5 @@ function createFlow(id) {
275
289
  }
276
290
 
277
291
  export { Flow, createFlow };
278
- //# sourceMappingURL=chunk-C4HYIJI3.js.map
279
- //# sourceMappingURL=chunk-C4HYIJI3.js.map
292
+ //# sourceMappingURL=chunk-7PBANEG3.js.map
293
+ //# sourceMappingURL=chunk-7PBANEG3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/flow.ts"],"names":[],"mappings":"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","file":"chunk-7PBANEG3.js","sourcesContent":["import { isNodeClass } from './node'\nimport type { EdgeDefinition, NodeClass, NodeDefinition, NodeFunction, UIGraph, WorkflowBlueprint } from './types'\n\n/**\n * Generates a deterministic hash for a function based on its source code and a unique counter.\n */\nlet hashCounter = 0\nfunction _hashFunction(fn: NodeFunction<any, any, any, any, any> | NodeClass<any, any, any, any, any>): string {\n\tconst source = fn.toString()\n\tlet hash = 0\n\tfor (let i = 0; i < source.length; i++) {\n\t\tconst char = source.charCodeAt(i)\n\t\thash = (hash << 5) - hash + char\n\t\thash = hash & hash // Convert to 32-bit integer\n\t}\n\t// Add counter to ensure uniqueness even for identical functions\n\treturn (Math.abs(hash) + hashCounter++).toString(16)\n}\n\n/**\n * A fluent API for programmatically constructing a WorkflowBlueprint.\n */\nexport class Flow<\n\tTContext extends Record<string, any> = Record<string, any>,\n\tTDependencies extends Record<string, any> = Record<string, any>,\n> {\n\tprivate blueprint: Partial<WorkflowBlueprint>\n\tprivate functionRegistry: Map<string, NodeFunction | NodeClass>\n\tprivate loopControllerIds: Map<string, string>\n\tprivate loopDefinitions: Array<{\n\t\tid: string\n\t\tstartNodeId: string\n\t\tendNodeId: string\n\t\tcondition: string\n\t}>\n\tprivate batchDefinitions: Array<{\n\t\tid: string\n\t\tscatterId: string\n\t\tgatherId: string\n\t}>\n\tprivate cycleEntryPoints: Map<string, string>\n\n\tconstructor(id: string) {\n\t\tthis.blueprint = { id, nodes: [], edges: [] }\n\t\tthis.functionRegistry = new Map()\n\t\tthis.loopControllerIds = new Map()\n\t\tthis.loopDefinitions = []\n\t\tthis.batchDefinitions = []\n\t\tthis.cycleEntryPoints = new Map()\n\t}\n\n\tnode<TInput = any, TOutput = any, TAction extends string = string>(\n\t\tid: string,\n\t\timplementation:\n\t\t\t| NodeFunction<TContext, TDependencies, TInput, TOutput, TAction>\n\t\t\t| NodeClass<TContext, TDependencies, TInput, TOutput, TAction>,\n\t\toptions?: Omit<NodeDefinition, 'id' | 'uses'>,\n\t): this {\n\t\tlet usesKey: string\n\n\t\tif (isNodeClass(implementation)) {\n\t\t\tusesKey =\n\t\t\t\timplementation.name && implementation.name !== 'BaseNode'\n\t\t\t\t\t? implementation.name\n\t\t\t\t\t: `class_${_hashFunction(implementation)}`\n\t\t\tthis.functionRegistry.set(usesKey, implementation)\n\t\t} else {\n\t\t\tusesKey = `fn_${_hashFunction(implementation)}`\n\t\t\tthis.functionRegistry.set(usesKey, implementation as unknown as NodeFunction)\n\t\t}\n\n\t\tconst nodeDef: NodeDefinition = { id, uses: usesKey, ...options }\n\t\tthis.blueprint.nodes?.push(nodeDef)\n\t\treturn this\n\t}\n\n\tedge(source: string, target: string, options?: Omit<EdgeDefinition, 'source' | 'target'>): this {\n\t\tconst edgeDef: EdgeDefinition = { source, target, ...options }\n\t\tthis.blueprint.edges?.push(edgeDef)\n\t\treturn this\n\t}\n\n\t/**\n\t * Creates a batch processing pattern.\n\t * It takes an input array, runs a worker node on each item in parallel, and gathers the results.\n\t * This method augments the Flow's TContext with a new key for the output array.\n\t *\n\t * @param id The base ID for this batch operation.\n\t * @param worker The node implementation to run on each item.\n\t * @param options Configuration for the batch operation.\n\t * @returns The Flow instance with an updated context type for chaining.\n\t */\n\tbatch<TWorkerInput, TWorkerOutput, TWorkerAction extends string, TOutputKey extends string>(\n\t\tid: string,\n\t\tworker:\n\t\t\t| NodeFunction<TContext, TDependencies, TWorkerInput, TWorkerOutput, TWorkerAction>\n\t\t\t| NodeClass<TContext, TDependencies, TWorkerInput, TWorkerOutput, TWorkerAction>,\n\t\toptions: {\n\t\t\t/** The key in the context that holds the input array for the batch. */\n\t\t\tinputKey: keyof TContext\n\t\t\t/** The key in the context where the array of results will be stored. */\n\t\t\toutputKey: TOutputKey\n\t\t\t/** The number of items to process in each chunk to limit memory usage. */\n\t\t\tchunkSize?: number\n\t\t},\n\t): Flow<TContext & { [K in TOutputKey]: TWorkerOutput[] }, TDependencies> {\n\t\tconst { inputKey, outputKey } = options\n\t\tconst scatterId = `${id}_scatter`\n\t\tconst gatherId = `${id}_gather`\n\n\t\tthis.batchDefinitions.push({ id, scatterId, gatherId })\n\n\t\t// register worker implementation under a unique key.\n\t\tlet workerUsesKey: string\n\t\tif (isNodeClass(worker)) {\n\t\t\tworkerUsesKey =\n\t\t\t\tworker.name && worker.name !== 'BaseNode' ? worker.name : `class_batch_worker_${_hashFunction(worker)}`\n\t\t\tthis.functionRegistry.set(workerUsesKey, worker)\n\t\t} else {\n\t\t\tworkerUsesKey = `fn_batch_worker_${_hashFunction(worker)}`\n\t\t\tthis.functionRegistry.set(workerUsesKey, worker as unknown as NodeFunction)\n\t\t}\n\n\t\t// scatter node: takes an array and dynamically schedules worker nodes\n\t\tthis.blueprint.nodes?.push({\n\t\t\tid: scatterId,\n\t\t\tuses: 'batch-scatter', // built-in\n\t\t\tinputs: inputKey as string,\n\t\t\tparams: { workerUsesKey, outputKey: outputKey as string, gatherNodeId: gatherId, chunkSize: options.chunkSize },\n\t\t})\n\n\t\t// gather node: waits for all workers to finish and collects the results\n\t\tthis.blueprint.nodes?.push({\n\t\t\tid: gatherId,\n\t\t\tuses: 'batch-gather', // built-in\n\t\t\tparams: { outputKey, gatherNodeId: gatherId },\n\t\t\tconfig: { joinStrategy: 'all' }, // important: must wait for all scattered jobs\n\t\t})\n\n\t\t// edge to connect scatter and gather nodes, orchestrator will manage dynamic workers\n\t\tthis.edge(scatterId, gatherId)\n\n\t\treturn this as unknown as Flow<TContext & { [K in TOutputKey]: TWorkerOutput[] }, TDependencies>\n\t}\n\n\t/**\n\t * Creates a sleep node that pauses workflow execution for a specified duration.\n\t * @param id A unique identifier for the sleep node.\n\t * @param options Configuration for the sleep duration.\n\t */\n\tsleep(\n\t\tid: string,\n\t\toptions: {\n\t\t\t/** The duration to sleep in milliseconds. */\n\t\t\tduration: number\n\t\t},\n\t): this {\n\t\tconst nodeDef: NodeDefinition = {\n\t\t\tid,\n\t\t\tuses: 'sleep',\n\t\t\tparams: { duration: options.duration },\n\t\t}\n\t\tthis.blueprint.nodes?.push(nodeDef)\n\t\treturn this\n\t}\n\n\t/**\n\t * Creates a wait node that pauses workflow execution for external input.\n\t * @param id A unique identifier for the wait node.\n\t * @param options Optional configuration for the wait node.\n\t */\n\twait(id: string, options?: Omit<NodeDefinition, 'id' | 'uses'>): this {\n\t\tconst nodeDef: NodeDefinition = { id, uses: 'wait', ...options }\n\t\tthis.blueprint.nodes?.push(nodeDef)\n\t\treturn this\n\t}\n\n\t/**\n\t * Creates a loop pattern in the workflow graph.\n\t * @param id A unique identifier for the loop construct.\n\t * @param options Defines the start, end, and continuation condition of the loop.\n\t * @param options.startNodeId The ID of the first node inside the loop body.\n\t * @param options.endNodeId The ID of the last node inside the loop body.\n\t * @param options.condition An expression that, if true, causes the loop to run again.\n\t */\n\tloop(\n\t\tid: string,\n\t\toptions: {\n\t\t\t/** The ID of the first node inside the loop body. */\n\t\t\tstartNodeId: string\n\t\t\t/** The ID of the last node inside the loop body. */\n\t\t\tendNodeId: string\n\t\t\t/** An expression that, if true, causes the loop to run again. */\n\t\t\tcondition: string\n\t\t},\n\t): this {\n\t\tconst { startNodeId, endNodeId, condition } = options\n\t\tconst controllerId = `${id}-loop`\n\n\t\tthis.loopControllerIds.set(id, controllerId)\n\n\t\tthis.loopDefinitions.push({ id, startNodeId, endNodeId, condition })\n\n\t\t// controller node: evaluates the loop condition\n\t\tthis.blueprint.nodes?.push({\n\t\t\tid: controllerId,\n\t\t\tuses: 'loop-controller', // built-in\n\t\t\tparams: { condition },\n\t\t\tconfig: { joinStrategy: 'any' }, // to allow re-execution on each loop iteration\n\t\t})\n\n\t\tthis.edge(endNodeId, controllerId)\n\n\t\tthis.edge(controllerId, startNodeId, {\n\t\t\taction: 'continue',\n\t\t\ttransform: `context.${endNodeId}`, // pass the end node's value to the start node\n\t\t})\n\n\t\treturn this\n\t}\n\n\tgetLoopControllerId(id: string): string {\n\t\tconst controllerId = this.loopControllerIds.get(id)\n\t\tif (!controllerId) {\n\t\t\tthrow new Error(`Loop with id '${id}' not found. Ensure you have defined it using the .loop() method.`)\n\t\t}\n\t\treturn controllerId\n\t}\n\n\t/**\n\t * Sets the preferred entry point for a cycle in non-DAG workflows.\n\t * This helps remove ambiguity when the runtime needs to choose a starting node for cycles.\n\t * @param nodeId The ID of the node to use as the entry point for cycles containing this node.\n\t */\n\tsetCycleEntryPoint(nodeId: string): this {\n\t\tthis.cycleEntryPoints.set(nodeId, nodeId)\n\t\treturn this\n\t}\n\n\ttoBlueprint(): WorkflowBlueprint {\n\t\tif (!this.blueprint.nodes || this.blueprint.nodes.length === 0) {\n\t\t\tthrow new Error('Cannot build a blueprint with no nodes.')\n\t\t}\n\n\t\tconst finalEdges: EdgeDefinition[] = []\n\t\tconst processedOriginalEdges = new Set<EdgeDefinition>()\n\t\tconst allOriginalEdges = this.blueprint.edges || []\n\n\t\t// loop edge re-wiring\n\t\tfor (const loopDef of this.loopDefinitions) {\n\t\t\tconst controllerId = this.getLoopControllerId(loopDef.id)\n\t\t\tconst edgesToRewire = allOriginalEdges.filter((e) => e.source === loopDef.endNodeId && e.target !== controllerId)\n\t\t\tfor (const edge of edgesToRewire) {\n\t\t\t\tfinalEdges.push({ ...edge, source: controllerId, action: edge.action || 'break' })\n\t\t\t\tprocessedOriginalEdges.add(edge)\n\t\t\t}\n\t\t}\n\n\t\t// batch edge re-wiring\n\t\tfor (const batchDef of this.batchDefinitions) {\n\t\t\tconst incomingEdges = allOriginalEdges.filter((e) => e.target === batchDef.id)\n\t\t\tfor (const edge of incomingEdges) {\n\t\t\t\tfinalEdges.push({ ...edge, target: batchDef.scatterId })\n\t\t\t\tprocessedOriginalEdges.add(edge)\n\t\t\t}\n\n\t\t\tconst outgoingEdges = allOriginalEdges.filter((e) => e.source === batchDef.id)\n\t\t\tfor (const edge of outgoingEdges) {\n\t\t\t\tfinalEdges.push({ ...edge, source: batchDef.gatherId })\n\t\t\t\tprocessedOriginalEdges.add(edge)\n\t\t\t}\n\t\t}\n\n\t\t// all remaining edges\n\t\tfor (const edge of allOriginalEdges) {\n\t\t\tif (!processedOriginalEdges.has(edge)) {\n\t\t\t\tfinalEdges.push(edge)\n\t\t\t}\n\t\t}\n\t\tthis.blueprint.edges = finalEdges\n\n\t\tfor (const loopDef of this.loopDefinitions) {\n\t\t\tconst startNode = this.blueprint.nodes?.find((n) => n.id === loopDef.startNodeId)\n\t\t\tconst endNode = this.blueprint.nodes?.find((n) => n.id === loopDef.endNodeId)\n\n\t\t\tif (!startNode) {\n\t\t\t\tthrow new Error(`Loop '${loopDef.id}' references non-existent start node '${loopDef.startNodeId}'.`)\n\t\t\t}\n\t\t\tif (!endNode) {\n\t\t\t\tthrow new Error(`Loop '${loopDef.id}' references non-existent end node '${loopDef.endNodeId}'.`)\n\t\t\t}\n\n\t\t\tstartNode.config = { ...startNode.config, joinStrategy: 'any' }\n\t\t\tendNode.config = { ...endNode.config, joinStrategy: 'any' }\n\t\t}\n\n\t\tif (this.cycleEntryPoints.size > 0) {\n\t\t\tthis.blueprint.metadata = {\n\t\t\t\t...this.blueprint.metadata,\n\t\t\t\tcycleEntryPoints: Array.from(this.cycleEntryPoints.keys()),\n\t\t\t}\n\t\t}\n\n\t\treturn this.blueprint as WorkflowBlueprint\n\t}\n\n\tgetFunctionRegistry() {\n\t\treturn this.functionRegistry\n\t}\n\n\ttoGraphRepresentation(): UIGraph {\n\t\tconst blueprint = this.toBlueprint()\n\t\tconst uiNodes: UIGraph['nodes'] = []\n\t\tconst uiEdges: UIGraph['edges'] = []\n\n\t\tconst ignoredNodeIds = new Set<string>()\n\n\t\t// replace loop-controllers with direct, cyclical edges\n\t\tfor (const loopDef of this.loopDefinitions) {\n\t\t\tconst controllerId = this.loopControllerIds.get(loopDef.id)\n\t\t\tif (!controllerId) continue\n\n\t\t\tignoredNodeIds.add(controllerId)\n\n\t\t\t// direct edge from the end of loop to start\n\t\t\tuiEdges.push({\n\t\t\t\tsource: loopDef.endNodeId,\n\t\t\t\ttarget: loopDef.startNodeId,\n\t\t\t\tdata: {\n\t\t\t\t\tisLoopback: true,\n\t\t\t\t\tcondition: loopDef.condition,\n\t\t\t\t\tlabel: `continue if: ${loopDef.condition}`,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\t// re-wire any 'break' edges\n\t\t\tconst breakEdges = blueprint.edges.filter((edge) => edge.source === controllerId && edge.action === 'break')\n\t\t\tfor (const breakEdge of breakEdges) {\n\t\t\t\tuiEdges.push({\n\t\t\t\t\t...breakEdge,\n\t\t\t\t\tsource: loopDef.endNodeId,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// replace scatter/gather pairs with a single representative \"worker\" node\n\t\tconst scatterNodes = blueprint.nodes.filter((n) => n.uses === 'batch-scatter')\n\t\tfor (const scatterNode of scatterNodes) {\n\t\t\tconst gatherNodeId = scatterNode.params?.gatherNodeId\n\t\t\tif (!gatherNodeId) continue\n\n\t\t\tignoredNodeIds.add(scatterNode.id)\n\t\t\tignoredNodeIds.add(gatherNodeId)\n\n\t\t\t// single node to represent parallel work\n\t\t\tconst batchId = scatterNode.id.replace('_scatter', '')\n\t\t\tconst gatherNode = blueprint.nodes.find((n) => n.id === gatherNodeId)\n\n\t\t\tuiNodes.push({\n\t\t\t\tid: batchId,\n\t\t\t\tuses: scatterNode.params?.workerUsesKey,\n\t\t\t\ttype: 'batch-worker',\n\t\t\t\tdata: {\n\t\t\t\t\tlabel: `Batch: ${batchId}`,\n\t\t\t\t\tisBatchPlaceholder: true,\n\t\t\t\t\tworkerUsesKey: scatterNode.params?.workerUsesKey,\n\t\t\t\t\tinputKey: scatterNode.inputs,\n\t\t\t\t\toutputKey: gatherNode?.params?.outputKey,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\t// re-wire incoming edges\n\t\t\tconst incomingEdges = blueprint.edges.filter((e) => e.target === scatterNode.id)\n\t\t\tfor (const edge of incomingEdges) {\n\t\t\t\tuiEdges.push({ ...edge, target: batchId })\n\t\t\t}\n\n\t\t\t// re-wire outgoing edges\n\t\t\tconst outgoingEdges = blueprint.edges.filter((e) => e.source === gatherNodeId)\n\t\t\tfor (const edge of outgoingEdges) {\n\t\t\t\tuiEdges.push({ ...edge, source: batchId })\n\t\t\t}\n\t\t}\n\n\t\tfor (const node of blueprint.nodes) {\n\t\t\tif (!ignoredNodeIds.has(node.id)) {\n\t\t\t\tuiNodes.push(node)\n\t\t\t}\n\t\t}\n\n\t\tfor (const edge of blueprint.edges) {\n\t\t\tif (!ignoredNodeIds.has(edge.source) && !ignoredNodeIds.has(edge.target)) {\n\t\t\t\tconst alreadyAdded = uiEdges.some(\n\t\t\t\t\t(e) => e.source === edge.source && e.target === edge.target && e.action === edge.action,\n\t\t\t\t)\n\t\t\t\tif (!alreadyAdded) {\n\t\t\t\t\tuiEdges.push(edge)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { nodes: uiNodes, edges: uiEdges }\n\t}\n}\n\n/**\n * Helper function to create a new Flow builder instance.\n */\nexport function createFlow<\n\tTContext extends Record<string, any> = Record<string, any>,\n\tTDependencies extends Record<string, any> = Record<string, any>,\n>(id: string): Flow<TContext, TDependencies> {\n\treturn new Flow(id)\n}\n"]}
@@ -1,15 +1,17 @@
1
- import { WorkflowLogicHandler } from './chunk-MCGK3FXQ.js';
2
1
  import { NodeExecutorFactory } from './chunk-DL7KVYZF.js';
3
- import { SubflowNode } from './chunk-5KKSQWSC.js';
4
- import { WaitNode } from './chunk-CD3Q4N6V.js';
2
+ import { WorkflowScheduler } from './chunk-LM4ACVHL.js';
3
+ import { WorkflowLogicHandler } from './chunk-MCGK3FXQ.js';
4
+ import { SleepNode } from './chunk-LJ4COM7S.js';
5
+ import { SubflowNode } from './chunk-K6LPGUPR.js';
5
6
  import { GraphTraverser } from './chunk-G5BGBPFP.js';
7
+ import { WaitNode } from './chunk-GVF7GQXQ.js';
6
8
  import { sanitizeBlueprint } from './chunk-DSYAC4WB.js';
7
9
  import { BatchGatherNode } from './chunk-BC4G7OM6.js';
8
10
  import { BatchScatterNode } from './chunk-RM677CNU.js';
9
11
  import { analyzeBlueprint } from './chunk-233SESC2.js';
10
- import { DefaultOrchestrator } from './chunk-33NO4PUJ.js';
11
- import { ExecutionContext } from './chunk-FRKO3WX4.js';
12
- import { WorkflowState } from './chunk-CD4FUZOJ.js';
12
+ import { DefaultOrchestrator } from './chunk-NDWVLU7J.js';
13
+ import { ExecutionContext } from './chunk-KXXEA5VE.js';
14
+ import { WorkflowState } from './chunk-OO3FF3DF.js';
13
15
  import { NullLogger } from './chunk-4PELJWF7.js';
14
16
  import { JsonSerializer } from './chunk-CYHZ2YVH.js';
15
17
  import { DIContainer, ServiceTokens } from './chunk-WWGFIYKW.js';
@@ -32,6 +34,10 @@ var FlowRuntime = class {
32
34
  options;
33
35
  logicHandler;
34
36
  executorFactory;
37
+ scheduler;
38
+ getBlueprint(id) {
39
+ return this.blueprints[id];
40
+ }
35
41
  constructor(containerOrOptions, legacyOptions) {
36
42
  if (containerOrOptions instanceof DIContainer) {
37
43
  this.container = containerOrOptions;
@@ -46,6 +52,7 @@ var FlowRuntime = class {
46
52
  this.dependencies = this.container.resolve(ServiceTokens.Dependencies);
47
53
  this.options = legacyOptions || {};
48
54
  this.orchestrator = this.container.resolve(ServiceTokens.Orchestrator);
55
+ this.scheduler = new WorkflowScheduler(this);
49
56
  } else {
50
57
  const options = containerOrOptions;
51
58
  this.logger = options.logger || new NullLogger();
@@ -66,6 +73,7 @@ var FlowRuntime = class {
66
73
  };
67
74
  const builtInNodes = {
68
75
  wait: WaitNode,
76
+ sleep: SleepNode,
69
77
  subflow: SubflowNode,
70
78
  "batch-scatter": BatchScatterNode,
71
79
  "batch-gather": BatchGatherNode,
@@ -73,6 +81,7 @@ var FlowRuntime = class {
73
81
  };
74
82
  this.registry = new Map(Object.entries({ ...builtInNodes, ...options.registry || {} }));
75
83
  this.blueprints = options.blueprints || {};
84
+ this.scheduler = new WorkflowScheduler(this);
76
85
  this.dependencies = options.dependencies || {};
77
86
  this.options = options;
78
87
  this.container = null;
@@ -168,6 +177,21 @@ var FlowRuntime = class {
168
177
  errors: result.errors
169
178
  }
170
179
  });
180
+ if (result.status === "awaiting") {
181
+ const awaitingNodeIds = executionContext.state.getAwaitingNodeIds();
182
+ for (const nodeId of awaitingNodeIds) {
183
+ const details = executionContext.state.getAwaitingDetails(nodeId);
184
+ if (details?.reason === "timer") {
185
+ this.scheduler.registerAwaitingWorkflow(
186
+ executionContext.executionId,
187
+ executionContext.blueprint.id,
188
+ result.serializedContext,
189
+ nodeId,
190
+ details.wakeUpAt
191
+ );
192
+ }
193
+ }
194
+ }
171
195
  return result;
172
196
  } catch (error) {
173
197
  const duration = Date.now() - startTime;
@@ -220,6 +244,12 @@ var FlowRuntime = class {
220
244
  throw error;
221
245
  }
222
246
  }
247
+ startScheduler() {
248
+ this.scheduler.start();
249
+ }
250
+ stopScheduler() {
251
+ this.scheduler.stop();
252
+ }
223
253
  _setupResumedExecutionContext(blueprint, workflowState, options) {
224
254
  const executionId = globalThis.crypto?.randomUUID();
225
255
  const nodeRegistry = this._createExecutionRegistry(options?.functionRegistry);
@@ -442,5 +472,5 @@ var FlowRuntime = class {
442
472
  };
443
473
 
444
474
  export { FlowRuntime };
445
- //# sourceMappingURL=chunk-IB2BISIC.js.map
446
- //# sourceMappingURL=chunk-IB2BISIC.js.map
475
+ //# sourceMappingURL=chunk-CHG6O6JX.js.map
476
+ //# sourceMappingURL=chunk-CHG6O6JX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/runtime.ts"],"names":[],"mappings":"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","file":"chunk-CHG6O6JX.js","sourcesContent":["import type { BlueprintAnalysis } from '../analysis'\nimport { analyzeBlueprint } from '../analysis'\nimport { DIContainer, ServiceTokens } from '../container'\nimport { FlowcraftError } from '../errors'\nimport { PropertyEvaluator } from '../evaluator'\nimport { NullLogger } from '../logger'\nimport { BatchGatherNode } from '../nodes/batch-gather'\nimport { BatchScatterNode } from '../nodes/batch-scatter'\nimport { SleepNode } from '../nodes/sleep'\nimport { SubflowNode } from '../nodes/subflow'\nimport { WaitNode } from '../nodes/wait'\nimport { sanitizeBlueprint } from '../sanitizer'\nimport { JsonSerializer } from '../serializer'\nimport type {\n\tContextImplementation,\n\tEdgeDefinition,\n\tIEvaluator,\n\tIEventBus,\n\tILogger,\n\tISerializer,\n\tMiddleware,\n\tNodeClass,\n\tNodeDefinition,\n\tNodeFunction,\n\tNodeResult,\n\tRuntimeOptions,\n\tWorkflowBlueprint,\n\tWorkflowError,\n\tWorkflowResult,\n} from '../types'\nimport { ExecutionContext } from './execution-context'\nimport { NodeExecutorFactory } from './node-executor-factory'\nimport { DefaultOrchestrator } from './orchestrator'\nimport { WorkflowScheduler } from './scheduler'\nimport { WorkflowState } from './state'\nimport { GraphTraverser } from './traverser'\nimport type { IOrchestrator, IRuntime } from './types'\nimport { WorkflowLogicHandler } from './workflow-logic-handler'\n\nexport class FlowRuntime<TContext extends Record<string, any>, TDependencies extends Record<string, any>>\n\timplements IRuntime<TContext, TDependencies>\n{\n\tprivate container: DIContainer\n\tpublic registry: Map<string, NodeFunction | NodeClass>\n\tprivate blueprints: Record<string, WorkflowBlueprint>\n\tpublic dependencies: TDependencies\n\tpublic logger: ILogger\n\tpublic eventBus: IEventBus\n\tpublic serializer: ISerializer\n\tpublic middleware: Middleware[]\n\tpublic evaluator: IEvaluator\n\tprivate analysisCache: WeakMap<WorkflowBlueprint, BlueprintAnalysis>\n\tpublic orchestrator: IOrchestrator\n\tpublic options: RuntimeOptions<TDependencies>\n\tprivate readonly logicHandler: WorkflowLogicHandler\n\tprivate readonly executorFactory: NodeExecutorFactory\n\tpublic scheduler: WorkflowScheduler\n\n\tgetBlueprint(id: string): WorkflowBlueprint | undefined {\n\t\treturn this.blueprints[id]\n\t}\n\n\tconstructor(container: DIContainer, options?: RuntimeOptions<TDependencies>)\n\tconstructor(options: RuntimeOptions<TDependencies>)\n\tconstructor(\n\t\tcontainerOrOptions: DIContainer | RuntimeOptions<TDependencies>,\n\t\tlegacyOptions?: RuntimeOptions<TDependencies>,\n\t) {\n\t\tif (containerOrOptions instanceof DIContainer) {\n\t\t\tthis.container = containerOrOptions\n\t\t\tthis.logger = this.container.resolve<ILogger>(ServiceTokens.Logger)\n\t\t\tthis.serializer = this.container.resolve<ISerializer>(ServiceTokens.Serializer)\n\t\t\tthis.evaluator = this.container.resolve<IEvaluator>(ServiceTokens.Evaluator)\n\t\t\tthis.eventBus = this.container.resolve<IEventBus>(ServiceTokens.EventBus) || { emit: async () => {} }\n\t\t\tthis.middleware = this.container.resolve<Middleware[]>(ServiceTokens.Middleware) || []\n\t\t\tthis.registry = this.container.resolve<Map<string, NodeFunction | NodeClass>>(ServiceTokens.NodeRegistry)\n\t\t\tthis.blueprints = this.container.resolve<Record<string, WorkflowBlueprint>>(ServiceTokens.BlueprintRegistry)\n\t\t\tthis.dependencies = this.container.resolve<TDependencies>(ServiceTokens.Dependencies)\n\t\t\tthis.options = legacyOptions || ({} as RuntimeOptions<TDependencies>)\n\t\t\tthis.orchestrator = this.container.resolve<IOrchestrator>(ServiceTokens.Orchestrator)\n\t\t\tthis.scheduler = new WorkflowScheduler(this)\n\t\t} else {\n\t\t\tconst options = containerOrOptions\n\t\t\tthis.logger = options.logger || new NullLogger()\n\t\t\tthis.serializer = options.serializer || new JsonSerializer()\n\t\t\tthis.evaluator = options.evaluator || new PropertyEvaluator()\n\t\t\tthis.eventBus = options.eventBus || { emit: async () => {} }\n\t\t\tthis.middleware = options.middleware || []\n\t\t\tconst loopControllerFunction: NodeFunction = async (context) => {\n\t\t\t\tconst condition = context.params.condition\n\t\t\t\tconst contextData = await context.context.toJSON()\n\t\t\t\tconst result = this.evaluator.evaluate(condition, contextData)\n\t\t\t\tif (result) {\n\t\t\t\t\treturn { action: 'continue' }\n\t\t\t\t} else {\n\t\t\t\t\treturn { action: 'break', output: null }\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst builtInNodes = {\n\t\t\t\twait: WaitNode,\n\t\t\t\tsleep: SleepNode,\n\t\t\t\tsubflow: SubflowNode,\n\t\t\t\t'batch-scatter': BatchScatterNode,\n\t\t\t\t'batch-gather': BatchGatherNode,\n\t\t\t\t'loop-controller': loopControllerFunction,\n\t\t\t}\n\t\t\tthis.registry = new Map(Object.entries({ ...builtInNodes, ...(options.registry || {}) }))\n\t\t\tthis.blueprints = options.blueprints || {}\n\t\t\tthis.scheduler = new WorkflowScheduler(this)\n\t\t\tthis.dependencies = options.dependencies || ({} as TDependencies)\n\t\t\tthis.options = options\n\t\t\tthis.container = null as any\n\t\t}\n\t\tthis.orchestrator = this.container?.has(ServiceTokens.Orchestrator)\n\t\t\t? this.container.resolve<IOrchestrator>(ServiceTokens.Orchestrator)\n\t\t\t: new DefaultOrchestrator()\n\t\tthis.analysisCache = new WeakMap()\n\t\tthis.logicHandler = new WorkflowLogicHandler(this.evaluator, this.eventBus)\n\t\tthis.executorFactory = new NodeExecutorFactory(this.eventBus)\n\t}\n\n\tprivate _setupExecutionContext(\n\t\tblueprint: WorkflowBlueprint,\n\t\tinitialState: Partial<TContext> | string,\n\t\toptions?: {\n\t\t\tfunctionRegistry?: Map<string, any>\n\t\t\tstrict?: boolean\n\t\t\tsignal?: AbortSignal\n\t\t\tconcurrency?: number\n\t\t},\n\t): ExecutionContext<TContext, TDependencies> {\n\t\tconst executionId = globalThis.crypto?.randomUUID()\n\t\tconst contextData =\n\t\t\ttypeof initialState === 'string' ? (this.serializer.deserialize(initialState) as Partial<TContext>) : initialState\n\t\tblueprint = sanitizeBlueprint(blueprint)\n\t\tconst state = new WorkflowState<TContext>(contextData)\n\t\tconst nodeRegistry = this._createExecutionRegistry(options?.functionRegistry)\n\t\treturn new ExecutionContext(\n\t\t\tblueprint,\n\t\t\tstate,\n\t\t\tnodeRegistry,\n\t\t\texecutionId,\n\t\t\tthis,\n\t\t\t{\n\t\t\t\tlogger: this.logger,\n\t\t\t\teventBus: this.eventBus,\n\t\t\t\tserializer: this.serializer,\n\t\t\t\tevaluator: this.evaluator,\n\t\t\t\tmiddleware: this.middleware,\n\t\t\t\tdependencies: this.dependencies,\n\t\t\t},\n\t\t\toptions?.signal,\n\t\t\toptions?.concurrency,\n\t\t)\n\t}\n\n\tasync run(\n\t\tblueprint: WorkflowBlueprint,\n\t\tinitialState: Partial<TContext> | string = {},\n\t\toptions?: {\n\t\t\tfunctionRegistry?: Map<string, any>\n\t\t\tstrict?: boolean\n\t\t\tsignal?: AbortSignal\n\t\t\tconcurrency?: number\n\t\t},\n\t): Promise<WorkflowResult<TContext>> {\n\t\tconst startTime = Date.now()\n\t\tconst executionContext = this._setupExecutionContext(blueprint, initialState, options)\n\n\t\tthis.logger.info(`Starting workflow execution`, {\n\t\t\tblueprintId: executionContext.blueprint.id,\n\t\t\texecutionId: executionContext.executionId,\n\t\t})\n\n\t\ttry {\n\t\t\tawait this.eventBus.emit({\n\t\t\t\ttype: 'workflow:start',\n\t\t\t\tpayload: { blueprintId: executionContext.blueprint.id, executionId: executionContext.executionId },\n\t\t\t})\n\t\t\tawait this.eventBus.emit({\n\t\t\t\ttype: 'workflow:resume',\n\t\t\t\tpayload: { blueprintId: executionContext.blueprint.id, executionId: executionContext.executionId },\n\t\t\t})\n\t\t\tconst analysis =\n\t\t\t\tthis.analysisCache.get(executionContext.blueprint) ??\n\t\t\t\t(() => {\n\t\t\t\t\tconst computed = analyzeBlueprint(executionContext.blueprint)\n\t\t\t\t\tthis.analysisCache.set(executionContext.blueprint, computed)\n\t\t\t\t\treturn computed\n\t\t\t\t})()\n\t\t\tif (options?.strict && !analysis.isDag) {\n\t\t\t\tthrow new Error(`Workflow '${executionContext.blueprint.id}' failed strictness check: Cycles are not allowed.`)\n\t\t\t}\n\t\t\tif (!analysis.isDag) {\n\t\t\t\tthis.logger.warn(`Workflow contains cycles`, {\n\t\t\t\t\tblueprintId: executionContext.blueprint.id,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst traverser = new GraphTraverser(executionContext.blueprint, options?.strict === true)\n\t\t\tconst result = await this.orchestrator.run(executionContext, traverser)\n\n\t\t\tconst duration = Date.now() - startTime\n\t\t\tif (result.status === 'stalled') {\n\t\t\t\tawait this.eventBus.emit({\n\t\t\t\t\ttype: 'workflow:stall',\n\t\t\t\t\tpayload: {\n\t\t\t\t\t\tblueprintId: executionContext.blueprint.id,\n\t\t\t\t\t\texecutionId: executionContext.executionId,\n\t\t\t\t\t\tremainingNodes: traverser.getAllNodeIds().size - executionContext.state.getCompletedNodes().size,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\tawait this.eventBus.emit({\n\t\t\t\t\ttype: 'workflow:pause',\n\t\t\t\t\tpayload: { blueprintId: executionContext.blueprint.id, executionId: executionContext.executionId },\n\t\t\t\t})\n\t\t\t}\n\t\t\tthis.logger.info(`Workflow execution completed`, {\n\t\t\t\tblueprintId: executionContext.blueprint.id,\n\t\t\t\texecutionId: executionContext.executionId,\n\t\t\t\tstatus: result.status,\n\t\t\t\tduration,\n\t\t\t\terrors: result.errors?.length || 0,\n\t\t\t})\n\t\t\tawait this.eventBus.emit({\n\t\t\t\ttype: 'workflow:finish',\n\t\t\t\tpayload: {\n\t\t\t\t\tblueprintId: executionContext.blueprint.id,\n\t\t\t\t\texecutionId: executionContext.executionId,\n\t\t\t\t\tstatus: result.status,\n\t\t\t\t\terrors: result.errors,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tif (result.status === 'awaiting') {\n\t\t\t\tconst awaitingNodeIds = executionContext.state.getAwaitingNodeIds()\n\t\t\t\tfor (const nodeId of awaitingNodeIds) {\n\t\t\t\t\tconst details = executionContext.state.getAwaitingDetails(nodeId)\n\t\t\t\t\tif (details?.reason === 'timer') {\n\t\t\t\t\t\tthis.scheduler.registerAwaitingWorkflow(\n\t\t\t\t\t\t\texecutionContext.executionId,\n\t\t\t\t\t\t\texecutionContext.blueprint.id,\n\t\t\t\t\t\t\tresult.serializedContext,\n\t\t\t\t\t\t\tnodeId,\n\t\t\t\t\t\t\tdetails.wakeUpAt,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tconst duration = Date.now() - startTime\n\t\t\tconst workflowError: WorkflowError = {\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\tisFatal: false,\n\t\t\t\tname: 'WorkflowError',\n\t\t\t}\n\t\t\tawait this.eventBus.emit({\n\t\t\t\ttype: 'workflow:finish',\n\t\t\t\tpayload: {\n\t\t\t\t\tblueprintId: executionContext.blueprint.id,\n\t\t\t\t\texecutionId: executionContext.executionId,\n\t\t\t\t\tstatus: 'cancelled',\n\t\t\t\t\terrors: [workflowError],\n\t\t\t\t},\n\t\t\t})\n\t\t\tif (\n\t\t\t\terror instanceof DOMException\n\t\t\t\t\t? error.name === 'AbortError'\n\t\t\t\t\t: error instanceof FlowcraftError && error.message.includes('cancelled')\n\t\t\t) {\n\t\t\t\tthis.logger.info(`Workflow execution cancelled`, {\n\t\t\t\t\tblueprintId: executionContext.blueprint.id,\n\t\t\t\t\texecutionId: executionContext.executionId,\n\t\t\t\t\tduration,\n\t\t\t\t})\n\t\t\t\tawait this.eventBus.emit({\n\t\t\t\t\ttype: 'workflow:pause',\n\t\t\t\t\tpayload: { blueprintId: executionContext.blueprint.id, executionId: executionContext.executionId },\n\t\t\t\t})\n\t\t\t\tawait this.eventBus.emit({\n\t\t\t\t\ttype: 'workflow:finish',\n\t\t\t\t\tpayload: {\n\t\t\t\t\t\tblueprintId: executionContext.blueprint.id,\n\t\t\t\t\t\texecutionId: executionContext.executionId,\n\t\t\t\t\t\tstatus: 'cancelled',\n\t\t\t\t\t\terrors: [workflowError],\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\treturn {\n\t\t\t\t\tcontext: {} as TContext,\n\t\t\t\t\tserializedContext: '{}',\n\t\t\t\t\tstatus: 'cancelled',\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.logger.error(`Workflow execution failed`, {\n\t\t\t\tblueprintId: executionContext.blueprint.id,\n\t\t\t\texecutionId: executionContext.executionId,\n\t\t\t\tduration,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t})\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tstartScheduler(): void {\n\t\tthis.scheduler.start()\n\t}\n\n\tstopScheduler(): void {\n\t\tthis.scheduler.stop()\n\t}\n\n\tprivate _setupResumedExecutionContext(\n\t\tblueprint: WorkflowBlueprint,\n\t\tworkflowState: WorkflowState<TContext>,\n\t\toptions?: {\n\t\t\tfunctionRegistry?: Map<string, any>\n\t\t\tstrict?: boolean\n\t\t\tsignal?: AbortSignal\n\t\t\tconcurrency?: number\n\t\t},\n\t): ExecutionContext<TContext, TDependencies> {\n\t\tconst executionId = globalThis.crypto?.randomUUID()\n\t\tconst nodeRegistry = this._createExecutionRegistry(options?.functionRegistry)\n\t\treturn new ExecutionContext(\n\t\t\tblueprint,\n\t\t\tworkflowState,\n\t\t\tnodeRegistry,\n\t\t\texecutionId,\n\t\t\tthis,\n\t\t\t{\n\t\t\t\tlogger: this.logger,\n\t\t\t\teventBus: this.eventBus,\n\t\t\t\tserializer: this.serializer,\n\t\t\t\tevaluator: this.evaluator,\n\t\t\t\tmiddleware: this.middleware,\n\t\t\t\tdependencies: this.dependencies,\n\t\t\t},\n\t\t\toptions?.signal,\n\t\t)\n\t}\n\n\tasync resume(\n\t\tblueprint: WorkflowBlueprint,\n\t\tserializedContext: string,\n\t\tresumeData: { output?: any; action?: string },\n\t\tnodeId?: string,\n\t\toptions?: {\n\t\t\tfunctionRegistry?: Map<string, any>\n\t\t\tstrict?: boolean\n\t\t\tsignal?: AbortSignal\n\t\t\tconcurrency?: number\n\t\t},\n\t): Promise<WorkflowResult<TContext>> {\n\t\tconst executionId = globalThis.crypto?.randomUUID()\n\t\tconst workflowState = new WorkflowState<TContext>(\n\t\t\tthis.serializer.deserialize(serializedContext) as Partial<TContext>,\n\t\t)\n\n\t\tconst awaitingNodeIds = workflowState.getAwaitingNodeIds()\n\t\tif (awaitingNodeIds.length === 0) {\n\t\t\tthrow new FlowcraftError('Cannot resume: The provided context is not in an awaiting state.', {\n\t\t\t\tisFatal: true,\n\t\t\t})\n\t\t}\n\n\t\tconst awaitingNodeId = nodeId || awaitingNodeIds[0]\n\t\tif (!awaitingNodeIds.includes(awaitingNodeId)) {\n\t\t\tthrow new FlowcraftError(`Cannot resume: Node '${awaitingNodeId}' is not in an awaiting state.`, {\n\t\t\t\tisFatal: true,\n\t\t\t})\n\t\t}\n\n\t\tconst awaitingNodeDef = blueprint.nodes.find((n) => n.id === awaitingNodeId)\n\t\tif (!awaitingNodeDef) {\n\t\t\tthrow new FlowcraftError(`Awaiting node '${awaitingNodeId}' not found in blueprint.`, {\n\t\t\t\tnodeId: awaitingNodeId,\n\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\tisFatal: true,\n\t\t\t})\n\t\t}\n\n\t\tconst contextImpl = workflowState.getContext()\n\n\t\tif (awaitingNodeDef.uses === 'SubflowNode') {\n\t\t\tconst subflowStateKey = `_subflowState.${awaitingNodeId}`\n\t\t\tconst asyncContext = contextImpl\n\t\t\tconst subflowContext = (await asyncContext.get(subflowStateKey as any)) as string\n\n\t\t\tif (!subflowContext) {\n\t\t\t\tthrow new FlowcraftError(`Cannot resume: Subflow state for node '${awaitingNodeId}' not found.`, {\n\t\t\t\t\tnodeId: awaitingNodeId,\n\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t\tisFatal: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst blueprintId = awaitingNodeDef.params?.blueprintId\n\t\t\tif (!blueprintId) {\n\t\t\t\tthrow new FlowcraftError(`Subflow node '${awaitingNodeId}' is missing the 'blueprintId' parameter.`, {\n\t\t\t\t\tnodeId: awaitingNodeId,\n\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t\tisFatal: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst subBlueprint = this.blueprints[blueprintId]\n\t\t\tif (!subBlueprint) {\n\t\t\t\tthrow new FlowcraftError(`Sub-blueprint with ID '${blueprintId}' not found in runtime registry.`, {\n\t\t\t\t\tnodeId: awaitingNodeId,\n\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t\tisFatal: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst subflowResumeResult = await this.resume(subBlueprint, subflowContext, resumeData, undefined, options)\n\n\t\t\tif (subflowResumeResult.status !== 'completed') {\n\t\t\t\tthrow new FlowcraftError(\n\t\t\t\t\t`Resumed subflow '${subBlueprint.id}' did not complete. Status: ${subflowResumeResult.status}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tnodeId: awaitingNodeId,\n\t\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t\t\tisFatal: false,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// mirror the output extraction logic from SubflowNode.exec\n\t\t\tconst subflowFinalContext = subflowResumeResult.context as Record<string, any>\n\t\t\tlet finalSubflowOutput: any\n\t\t\tconst subAnalysis = analyzeBlueprint(subBlueprint)\n\n\t\t\tif (awaitingNodeDef.params?.outputs) {\n\t\t\t\tfinalSubflowOutput = subflowFinalContext\n\t\t\t} else if (subAnalysis.terminalNodeIds.length === 1) {\n\t\t\t\tconst terminalId = subAnalysis.terminalNodeIds[0]\n\t\t\t\tfinalSubflowOutput = subflowFinalContext[`_outputs.${terminalId}`]\n\t\t\t} else {\n\t\t\t\tconst terminalOutputs: Record<string, any> = {}\n\t\t\t\tfor (const terminalId of subAnalysis.terminalNodeIds) {\n\t\t\t\t\tterminalOutputs[terminalId] = subflowFinalContext[`_outputs.${terminalId}`]\n\t\t\t\t}\n\t\t\t\tfinalSubflowOutput = terminalOutputs\n\t\t\t}\n\n\t\t\tresumeData = { output: finalSubflowOutput }\n\n\t\t\tawait contextImpl.delete(subflowStateKey as any)\n\t\t}\n\n\t\tworkflowState.addCompletedNode(awaitingNodeId, resumeData.output)\n\n\t\tconst nextSteps = await this.determineNextNodes(blueprint, awaitingNodeId, resumeData, contextImpl, executionId)\n\n\t\tif (nextSteps.length === 0) {\n\t\t\tworkflowState.clearAwaiting(awaitingNodeId)\n\t\t\tconst result = await workflowState.toResult(this.serializer)\n\t\t\tresult.status = 'completed'\n\t\t\treturn result\n\t\t}\n\n\t\tconst traverserForResume = new GraphTraverser(blueprint)\n\t\tconst allPredecessors = traverserForResume.getAllPredecessors()\n\n\t\tfor (const { node, edge } of nextSteps) {\n\t\t\tawait this.applyEdgeTransform(edge, resumeData, node, contextImpl, allPredecessors)\n\t\t}\n\n\t\tconst traverser = GraphTraverser.fromState(blueprint, workflowState)\n\n\t\tconst nextNodeDefs = nextSteps.map((s) => s.node)\n\t\tfor (const nodeDef of nextNodeDefs) {\n\t\t\ttraverser.addToFrontier(nodeDef.id)\n\t\t}\n\n\t\tworkflowState.clearAwaiting(awaitingNodeId)\n\n\t\tconst executionContext = this._setupResumedExecutionContext(blueprint, workflowState, options)\n\n\t\treturn await this.orchestrator.run(executionContext, traverser)\n\t}\n\n\tpublic _createExecutionRegistry(dynamicRegistry?: Map<string, any>): Map<string, NodeFunction | NodeClass> {\n\t\tconst executionRegistry = new Map(this.registry)\n\t\tif (dynamicRegistry) {\n\t\t\tfor (const [key, func] of dynamicRegistry.entries()) {\n\t\t\t\texecutionRegistry.set(key, func)\n\t\t\t}\n\t\t}\n\t\treturn executionRegistry\n\t}\n\n\tasync executeNode(\n\t\tblueprint: WorkflowBlueprint,\n\t\tnodeId: string,\n\t\tstate: WorkflowState<TContext>,\n\t\t_allPredecessors?: Map<string, Set<string>>,\n\t\tfunctionRegistry?: Map<string, any>,\n\t\texecutionId?: string,\n\t\tsignal?: AbortSignal,\n\t): Promise<NodeResult<any, any>> {\n\t\tconst nodeDef = blueprint.nodes.find((n) => n.id === nodeId)\n\t\tif (!nodeDef) {\n\t\t\tthrow new FlowcraftError(`Node '${nodeId}' not found in blueprint.`, {\n\t\t\t\tnodeId,\n\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\texecutionId,\n\t\t\t\tisFatal: false,\n\t\t\t})\n\t\t}\n\n\t\tconst contextImpl = state.getContext()\n\t\tconst asyncContext = contextImpl\n\n\t\tconst input = await this.resolveNodeInput(nodeDef.id, blueprint, asyncContext)\n\t\tconst nodeRegistry = new Map([...this.registry, ...(functionRegistry || new Map())])\n\n\t\tconst services = {\n\t\t\tlogger: this.logger,\n\t\t\teventBus: this.eventBus,\n\t\t\tserializer: this.serializer,\n\t\t\tevaluator: this.evaluator,\n\t\t\tmiddleware: this.middleware,\n\t\t\tdependencies: this.dependencies,\n\t\t}\n\t\tconst context = new ExecutionContext(blueprint, state, nodeRegistry, executionId || '', this, services, signal)\n\n\t\tconst executor = this.executorFactory.createExecutorForNode(nodeId, context)\n\n\t\tconst executionResult = await executor.execute(input)\n\n\t\tif (executionResult.status === 'success') {\n\t\t\treturn executionResult.result\n\t\t}\n\n\t\tif (executionResult.status === 'failed_with_fallback') {\n\t\t\tconst fallbackNode = blueprint.nodes.find((n: NodeDefinition) => n.id === executionResult.fallbackNodeId)\n\t\t\tif (!fallbackNode) {\n\t\t\t\tthrow new FlowcraftError(`Fallback node '${executionResult.fallbackNodeId}' not found in blueprint.`, {\n\t\t\t\t\tnodeId: nodeDef.id,\n\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t\texecutionId,\n\t\t\t\t\tisFatal: false,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst fallbackInput = await this.resolveNodeInput(fallbackNode.id, blueprint, asyncContext)\n\t\t\tconst fallbackExecutor = this.executorFactory.createExecutorForNode(fallbackNode.id, context)\n\n\t\t\tconst fallbackResult = await fallbackExecutor.execute(fallbackInput)\n\t\t\tif (fallbackResult.status === 'success') {\n\t\t\t\tstate.markFallbackExecuted()\n\t\t\t\tstate.addCompletedNode(executionResult.fallbackNodeId, fallbackResult.result.output)\n\t\t\t\tthis.logger.info(`Fallback execution completed`, {\n\t\t\t\t\tnodeId: nodeDef.id,\n\t\t\t\t\tfallbackNodeId: executionResult.fallbackNodeId,\n\t\t\t\t\texecutionId,\n\t\t\t\t})\n\t\t\t\treturn { ...fallbackResult.result, _fallbackExecuted: true }\n\t\t\t}\n\n\t\t\tthrow fallbackResult.error\n\t\t}\n\n\t\tthrow executionResult.error\n\t}\n\n\tpublic getExecutorForNode(nodeId: string, context: ExecutionContext<TContext, TDependencies>): any {\n\t\treturn this.executorFactory.createExecutorForNode(nodeId, context)\n\t}\n\n\tpublic createForSubflow(\n\t\tsubBlueprint: WorkflowBlueprint,\n\t\tinitialSubState: Partial<TContext>,\n\t\texecutionId: string,\n\t\tsignal?: AbortSignal,\n\t): ExecutionContext<TContext, TDependencies> {\n\t\tconst subState = new WorkflowState<TContext>(initialSubState)\n\t\treturn new ExecutionContext(\n\t\t\tsubBlueprint,\n\t\t\tsubState,\n\t\t\tthis.registry,\n\t\t\texecutionId,\n\t\t\tthis,\n\t\t\t{\n\t\t\t\tlogger: this.logger,\n\t\t\t\teventBus: this.eventBus,\n\t\t\t\tserializer: this.serializer,\n\t\t\t\tevaluator: this.evaluator,\n\t\t\t\tmiddleware: this.middleware,\n\t\t\t\tdependencies: this.dependencies,\n\t\t\t},\n\t\t\tsignal,\n\t\t)\n\t}\n\n\tasync determineNextNodes(\n\t\tblueprint: WorkflowBlueprint,\n\t\tnodeId: string,\n\t\tresult: NodeResult<any, any>,\n\t\tcontext: ContextImplementation<TContext>,\n\t\texecutionId?: string,\n\t): Promise<{ node: NodeDefinition; edge: EdgeDefinition }[]> {\n\t\treturn this.logicHandler.determineNextNodes(blueprint, nodeId, result, context, executionId)\n\t}\n\n\tpublic async applyEdgeTransform(\n\t\tedge: EdgeDefinition,\n\t\tsourceResult: NodeResult<any, any>,\n\t\ttargetNode: NodeDefinition,\n\t\tcontext: ContextImplementation<TContext>,\n\t\tallPredecessors?: Map<string, Set<string>>,\n\t): Promise<void> {\n\t\treturn this.logicHandler.applyEdgeTransform(edge, sourceResult, targetNode, context, allPredecessors)\n\t}\n\n\tpublic async resolveNodeInput(\n\t\tnodeId: string,\n\t\tblueprint: WorkflowBlueprint,\n\t\tcontext: ContextImplementation<TContext>,\n\t): Promise<any> {\n\t\treturn this.logicHandler.resolveNodeInput(nodeId, blueprint, context)\n\t}\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { StepByStepOrchestrator } from './chunk-G53CSLBF.js';
2
2
  import { GraphTraverser } from './chunk-G5BGBPFP.js';
3
- import { ExecutionContext } from './chunk-FRKO3WX4.js';
4
- import { WorkflowState } from './chunk-CD4FUZOJ.js';
3
+ import { ExecutionContext } from './chunk-KXXEA5VE.js';
4
+ import { WorkflowState } from './chunk-OO3FF3DF.js';
5
5
 
6
6
  // src/testing/stepper.ts
7
7
  async function createStepper(runtime, blueprint, functionRegistry, initialState = {}) {
@@ -72,5 +72,5 @@ async function createStepper(runtime, blueprint, functionRegistry, initialState
72
72
  }
73
73
 
74
74
  export { createStepper };
75
- //# sourceMappingURL=chunk-XNRIM27H.js.map
76
- //# sourceMappingURL=chunk-XNRIM27H.js.map
75
+ //# sourceMappingURL=chunk-GIJOZ3AN.js.map
76
+ //# sourceMappingURL=chunk-GIJOZ3AN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing/stepper.ts"],"names":[],"mappings":";;;;;;AAkFA,eAAsB,cACrB,OAAA,EACA,SAAA,EACA,gBAAA,EACA,YAAA,GAAkC,EAAC,EACG;AACtC,EAAA,MAAM,iBAAA,GAAoB,gBAAgB,SAAS,CAAA;AACnD,EAAA,MAAM,aAAA,GAAgB,gBAAgB,YAAY,CAAA;AAElD,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI,SAAA;AACJ,EAAA,MAAM,UAAoB,EAAC;AAE3B,EAAA,MAAM,YAAA,GAAe,IAAI,sBAAA,EAAuB;AAChD,EAAA,MAAM,WAAA,GAAc,UAAA,CAAW,MAAA,EAAQ,UAAA,EAAW;AAClD,EAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,CAAC,GAAG,OAAA,CAAQ,QAAA,EAAU,GAAG,gBAAgB,CAAC,CAAA;AAEvE,EAAA,MAAM,aAAa,MAAM;AACxB,IAAA,KAAA,GAAQ,IAAI,cAAwB,aAAa,CAAA;AACjD,IAAA,SAAA,GAAY,IAAI,eAAe,iBAAiB,CAAA;AAChD,IAAA,OAAA,CAAQ,MAAA,GAAS,CAAA;AAAA,EAClB,CAAA;AAEA,EAAA,UAAA,EAAW;AAEX,EAAA,MAAM,OAAA,GAAsC;AAAA,IAC3C,IAAI,KAAA,GAAQ;AACX,MAAA,OAAO,KAAA;AAAA,IACR,CAAA;AAAA,IACA,IAAI,SAAA,GAAY;AACf,MAAA,OAAO,SAAA;AAAA,IACR,CAAA;AAAA,IACA,MAAA,GAAS;AACR,MAAA,OAAO,CAAC,SAAA,CAAU,WAAA,EAAY,IAAK,CAAC,MAAM,UAAA,EAAW;AAAA,IACtD,CAAA;AAAA,IACA,KAAA,GAAQ;AACP,MAAA,UAAA,EAAW;AAAA,IACZ,CAAA;AAAA,IACA,MAAM,IAAA,GAAO;AACZ,MAAA,MAAM,iBAAA,GAAoB,QAAQ,GAAA,EAAI;AACtC,MAAA,IAAI,CAAC,iBAAA,EAAmB;AACvB,QAAA,OAAO,IAAA;AAAA,MACR;AAEA,MAAA,MAAM,iBAAA,GAAoB,OAAA,CAAQ,UAAA,CAAW,WAAA,CAAY,iBAAiB,CAAA;AAE1E,MAAA,KAAA,GAAQ,IAAI,cAAc,iBAAiB,CAAA;AAC3C,MAAA,SAAA,GAAY,cAAA,CAAe,SAAA,CAAU,iBAAA,EAAmB,KAAK,CAAA;AAE7D,MAAA,OAAO,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,UAAU,CAAA;AAAA,IACzC,CAAA;AAAA,IACA,MAAM,IAAA,CAAK,OAAA,GAA0D,EAAC,EAAG;AACxE,MAAA,IAAI,OAAA,CAAQ,QAAO,EAAG;AACrB,QAAA,OAAO,IAAA;AAAA,MACR;AAEA,MAAA,MAAM,qBAAqB,MAAM,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,UAAU,CAAA,EAAG,iBAAA;AACrE,MAAA,OAAA,CAAQ,KAAK,iBAAiB,CAAA;AAE9B,MAAA,MAAM,mBAAmB,IAAI,gBAAA;AAAA,QAC5B,iBAAA;AAAA,QACA,KAAA;AAAA,QACA,YAAA;AAAA,QACA,WAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,UACC,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,UAAU,OAAA,CAAQ,QAAA;AAAA,UAClB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,WAAW,OAAA,CAAQ,SAAA;AAAA,UACnB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,cAAc,OAAA,CAAQ;AAAA,SACvB;AAAA,QACA,OAAA,CAAQ,MAAA;AAAA,QACR,OAAA,CAAQ;AAAA,OACT;AACA,MAAA,OAAO,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,SAAS,CAAA;AAAA,IACpD;AAAA,GACD;AAEA,EAAA,OAAO,OAAA;AACR","file":"chunk-XNRIM27H.js","sourcesContent":["import type { FlowRuntime } from '../runtime'\nimport { ExecutionContext } from '../runtime/execution-context'\nimport { StepByStepOrchestrator } from '../runtime/orchestrators/step-by-step'\nimport { WorkflowState } from '../runtime/state'\nimport { GraphTraverser } from '../runtime/traverser'\nimport type { NodeClass, NodeFunction, WorkflowBlueprint, WorkflowResult } from '../types'\n\n/**\n * Represents the controlled, step-by-step execution of a workflow.\n * Returned by the `createStepper` utility.\n */\nexport interface IWorkflowStepper<TContext extends Record<string, any>> {\n\t/** The current state of the workflow. Can be inspected after each step. */\n\treadonly state: WorkflowState<TContext>\n\n\t/** The graph traverser instance. Can be used to inspect the frontier or completed nodes. */\n\treadonly traverser: GraphTraverser\n\n\t/**\n\t * Executes the next \"turn\" or batch of ready nodes in the workflow.\n\t * @param options Optional configuration for this specific step, like a cancellation signal.\n\t * @returns A `WorkflowResult` representing the state after the step, or `null` if the workflow has already completed.\n\t */\n\tnext(options?: { signal?: AbortSignal; concurrency?: number }): Promise<WorkflowResult<TContext> | null>\n\n\t/**\n\t * Reverts the workflow to its previous state.\n\t * @returns The `WorkflowResult` of the previous state, or `null` if there is no history to revert to.\n\t */\n\tprev(): Promise<WorkflowResult<TContext> | null>\n\n\t/**\n\t * Resets the stepper to its initial state, clearing all progress and history.\n\t */\n\treset(): void\n\n\t/**\n\t * A convenience method to check if the workflow has any more steps to run.\n\t * @returns `true` if the workflow is complete or stalled, `false` otherwise.\n\t */\n\tisDone(): boolean\n}\n\n/**\n * A test utility that creates a stepper to execute a workflow one \"turn\" at a time.\n * This is invaluable for debugging and writing fine-grained tests where you need to\n * assert the state of the workflow after each logical step.\n *\n * @example\n * // In your test file\n * it('should correctly execute step-by-step', async () => {\n * const runtime = new FlowRuntime({ ... });\n * const flow = createFlow('test')\n * .node('a', async () => ({ output: 10 }))\n * .node('b', async ({ input }) => ({ output: input * 2 }))\n * .edge('a', 'b');\n *\n * const stepper = await createStepper(runtime, flow.toBlueprint(), flow.getFunctionRegistry());\n *\n * // First step (executes node 'a')\n * const result1 = await stepper.next();\n * expect(stepper.isDone()).toBe(false);\n * expect(result1.status).toBe('stalled');\n * expect(result1.context._outputs.a).toBe(10);\n *\n * // Second step (executes node 'b')\n * const result2 = await stepper.next();\n * expect(stepper.isDone()).toBe(true);\n * expect(result2.status).toBe('completed');\n * expect(result2.context._outputs.b).toBe(20);\n *\n * // Final step (no more work)\n * const result3 = await stepper.next();\n * expect(result3).toBeNull();\n * });\n *\n * @param runtime The `FlowRuntime` instance, used for its configuration.\n * @param blueprint The `WorkflowBlueprint` to execute.\n * @param functionRegistry The function registry from createFlow, containing the node implementations.\n * @param initialState The initial state for the workflow run.\n * @returns A Promise that resolves to an `IWorkflowStepper` instance.\n */\nexport async function createStepper<TContext extends Record<string, any>, TDependencies extends Record<string, any>>(\n\truntime: FlowRuntime<TContext, TDependencies>,\n\tblueprint: WorkflowBlueprint,\n\tfunctionRegistry: Map<string, NodeFunction | NodeClass>,\n\tinitialState: Partial<TContext> = {},\n): Promise<IWorkflowStepper<TContext>> {\n\tconst _initialBlueprint = structuredClone(blueprint)\n\tconst _initialState = structuredClone(initialState)\n\n\tlet state: WorkflowState<TContext>\n\tlet traverser: GraphTraverser\n\tconst history: string[] = []\n\n\tconst orchestrator = new StepByStepOrchestrator()\n\tconst executionId = globalThis.crypto?.randomUUID()\n\tconst nodeRegistry = new Map([...runtime.registry, ...functionRegistry])\n\n\tconst initialize = () => {\n\t\tstate = new WorkflowState<TContext>(_initialState)\n\t\ttraverser = new GraphTraverser(_initialBlueprint)\n\t\thistory.length = 0\n\t}\n\n\tinitialize()\n\n\tconst stepper: IWorkflowStepper<TContext> = {\n\t\tget state() {\n\t\t\treturn state\n\t\t},\n\t\tget traverser() {\n\t\t\treturn traverser\n\t\t},\n\t\tisDone() {\n\t\t\treturn !traverser.hasMoreWork() && !state.isAwaiting()\n\t\t},\n\t\treset() {\n\t\t\tinitialize()\n\t\t},\n\t\tasync prev() {\n\t\t\tconst previousStateJson = history.pop()\n\t\t\tif (!previousStateJson) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst previousStateData = runtime.serializer.deserialize(previousStateJson) as Partial<TContext>\n\n\t\t\tstate = new WorkflowState(previousStateData)\n\t\t\ttraverser = GraphTraverser.fromState(_initialBlueprint, state)\n\n\t\t\treturn state.toResult(runtime.serializer)\n\t\t},\n\t\tasync next(options: { signal?: AbortSignal; concurrency?: number } = {}) {\n\t\t\tif (stepper.isDone()) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst serializedContext = (await state.toResult(runtime.serializer)).serializedContext\n\t\t\thistory.push(serializedContext)\n\n\t\t\tconst executionContext = new ExecutionContext(\n\t\t\t\t_initialBlueprint,\n\t\t\t\tstate,\n\t\t\t\tnodeRegistry,\n\t\t\t\texecutionId,\n\t\t\t\truntime,\n\t\t\t\t{\n\t\t\t\t\tlogger: runtime.logger,\n\t\t\t\t\teventBus: runtime.eventBus,\n\t\t\t\t\tserializer: runtime.serializer,\n\t\t\t\t\tevaluator: runtime.evaluator,\n\t\t\t\t\tmiddleware: runtime.middleware,\n\t\t\t\t\tdependencies: runtime.dependencies,\n\t\t\t\t},\n\t\t\t\toptions.signal,\n\t\t\t\toptions.concurrency,\n\t\t\t)\n\t\t\treturn orchestrator.run(executionContext, traverser)\n\t\t},\n\t}\n\n\treturn stepper\n}\n"]}
1
+ {"version":3,"sources":["../src/testing/stepper.ts"],"names":[],"mappings":";;;;;;AAkFA,eAAsB,cACrB,OAAA,EACA,SAAA,EACA,gBAAA,EACA,YAAA,GAAkC,EAAC,EACG;AACtC,EAAA,MAAM,iBAAA,GAAoB,gBAAgB,SAAS,CAAA;AACnD,EAAA,MAAM,aAAA,GAAgB,gBAAgB,YAAY,CAAA;AAElD,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI,SAAA;AACJ,EAAA,MAAM,UAAoB,EAAC;AAE3B,EAAA,MAAM,YAAA,GAAe,IAAI,sBAAA,EAAuB;AAChD,EAAA,MAAM,WAAA,GAAc,UAAA,CAAW,MAAA,EAAQ,UAAA,EAAW;AAClD,EAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,CAAC,GAAG,OAAA,CAAQ,QAAA,EAAU,GAAG,gBAAgB,CAAC,CAAA;AAEvE,EAAA,MAAM,aAAa,MAAM;AACxB,IAAA,KAAA,GAAQ,IAAI,cAAwB,aAAa,CAAA;AACjD,IAAA,SAAA,GAAY,IAAI,eAAe,iBAAiB,CAAA;AAChD,IAAA,OAAA,CAAQ,MAAA,GAAS,CAAA;AAAA,EAClB,CAAA;AAEA,EAAA,UAAA,EAAW;AAEX,EAAA,MAAM,OAAA,GAAsC;AAAA,IAC3C,IAAI,KAAA,GAAQ;AACX,MAAA,OAAO,KAAA;AAAA,IACR,CAAA;AAAA,IACA,IAAI,SAAA,GAAY;AACf,MAAA,OAAO,SAAA;AAAA,IACR,CAAA;AAAA,IACA,MAAA,GAAS;AACR,MAAA,OAAO,CAAC,SAAA,CAAU,WAAA,EAAY,IAAK,CAAC,MAAM,UAAA,EAAW;AAAA,IACtD,CAAA;AAAA,IACA,KAAA,GAAQ;AACP,MAAA,UAAA,EAAW;AAAA,IACZ,CAAA;AAAA,IACA,MAAM,IAAA,GAAO;AACZ,MAAA,MAAM,iBAAA,GAAoB,QAAQ,GAAA,EAAI;AACtC,MAAA,IAAI,CAAC,iBAAA,EAAmB;AACvB,QAAA,OAAO,IAAA;AAAA,MACR;AAEA,MAAA,MAAM,iBAAA,GAAoB,OAAA,CAAQ,UAAA,CAAW,WAAA,CAAY,iBAAiB,CAAA;AAE1E,MAAA,KAAA,GAAQ,IAAI,cAAc,iBAAiB,CAAA;AAC3C,MAAA,SAAA,GAAY,cAAA,CAAe,SAAA,CAAU,iBAAA,EAAmB,KAAK,CAAA;AAE7D,MAAA,OAAO,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,UAAU,CAAA;AAAA,IACzC,CAAA;AAAA,IACA,MAAM,IAAA,CAAK,OAAA,GAA0D,EAAC,EAAG;AACxE,MAAA,IAAI,OAAA,CAAQ,QAAO,EAAG;AACrB,QAAA,OAAO,IAAA;AAAA,MACR;AAEA,MAAA,MAAM,qBAAqB,MAAM,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,UAAU,CAAA,EAAG,iBAAA;AACrE,MAAA,OAAA,CAAQ,KAAK,iBAAiB,CAAA;AAE9B,MAAA,MAAM,mBAAmB,IAAI,gBAAA;AAAA,QAC5B,iBAAA;AAAA,QACA,KAAA;AAAA,QACA,YAAA;AAAA,QACA,WAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,UACC,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,UAAU,OAAA,CAAQ,QAAA;AAAA,UAClB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,WAAW,OAAA,CAAQ,SAAA;AAAA,UACnB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,cAAc,OAAA,CAAQ;AAAA,SACvB;AAAA,QACA,OAAA,CAAQ,MAAA;AAAA,QACR,OAAA,CAAQ;AAAA,OACT;AACA,MAAA,OAAO,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,SAAS,CAAA;AAAA,IACpD;AAAA,GACD;AAEA,EAAA,OAAO,OAAA;AACR","file":"chunk-GIJOZ3AN.js","sourcesContent":["import type { FlowRuntime } from '../runtime'\nimport { ExecutionContext } from '../runtime/execution-context'\nimport { StepByStepOrchestrator } from '../runtime/orchestrators/step-by-step'\nimport { WorkflowState } from '../runtime/state'\nimport { GraphTraverser } from '../runtime/traverser'\nimport type { NodeClass, NodeFunction, WorkflowBlueprint, WorkflowResult } from '../types'\n\n/**\n * Represents the controlled, step-by-step execution of a workflow.\n * Returned by the `createStepper` utility.\n */\nexport interface IWorkflowStepper<TContext extends Record<string, any>> {\n\t/** The current state of the workflow. Can be inspected after each step. */\n\treadonly state: WorkflowState<TContext>\n\n\t/** The graph traverser instance. Can be used to inspect the frontier or completed nodes. */\n\treadonly traverser: GraphTraverser\n\n\t/**\n\t * Executes the next \"turn\" or batch of ready nodes in the workflow.\n\t * @param options Optional configuration for this specific step, like a cancellation signal.\n\t * @returns A `WorkflowResult` representing the state after the step, or `null` if the workflow has already completed.\n\t */\n\tnext(options?: { signal?: AbortSignal; concurrency?: number }): Promise<WorkflowResult<TContext> | null>\n\n\t/**\n\t * Reverts the workflow to its previous state.\n\t * @returns The `WorkflowResult` of the previous state, or `null` if there is no history to revert to.\n\t */\n\tprev(): Promise<WorkflowResult<TContext> | null>\n\n\t/**\n\t * Resets the stepper to its initial state, clearing all progress and history.\n\t */\n\treset(): void\n\n\t/**\n\t * A convenience method to check if the workflow has any more steps to run.\n\t * @returns `true` if the workflow is complete or stalled, `false` otherwise.\n\t */\n\tisDone(): boolean\n}\n\n/**\n * A test utility that creates a stepper to execute a workflow one \"turn\" at a time.\n * This is invaluable for debugging and writing fine-grained tests where you need to\n * assert the state of the workflow after each logical step.\n *\n * @example\n * // In your test file\n * it('should correctly execute step-by-step', async () => {\n * const runtime = new FlowRuntime({ ... });\n * const flow = createFlow('test')\n * .node('a', async () => ({ output: 10 }))\n * .node('b', async ({ input }) => ({ output: input * 2 }))\n * .edge('a', 'b');\n *\n * const stepper = await createStepper(runtime, flow.toBlueprint(), flow.getFunctionRegistry());\n *\n * // First step (executes node 'a')\n * const result1 = await stepper.next();\n * expect(stepper.isDone()).toBe(false);\n * expect(result1.status).toBe('stalled');\n * expect(result1.context._outputs.a).toBe(10);\n *\n * // Second step (executes node 'b')\n * const result2 = await stepper.next();\n * expect(stepper.isDone()).toBe(true);\n * expect(result2.status).toBe('completed');\n * expect(result2.context._outputs.b).toBe(20);\n *\n * // Final step (no more work)\n * const result3 = await stepper.next();\n * expect(result3).toBeNull();\n * });\n *\n * @param runtime The `FlowRuntime` instance, used for its configuration.\n * @param blueprint The `WorkflowBlueprint` to execute.\n * @param functionRegistry The function registry from createFlow, containing the node implementations.\n * @param initialState The initial state for the workflow run.\n * @returns A Promise that resolves to an `IWorkflowStepper` instance.\n */\nexport async function createStepper<TContext extends Record<string, any>, TDependencies extends Record<string, any>>(\n\truntime: FlowRuntime<TContext, TDependencies>,\n\tblueprint: WorkflowBlueprint,\n\tfunctionRegistry: Map<string, NodeFunction | NodeClass>,\n\tinitialState: Partial<TContext> = {},\n): Promise<IWorkflowStepper<TContext>> {\n\tconst _initialBlueprint = structuredClone(blueprint)\n\tconst _initialState = structuredClone(initialState)\n\n\tlet state: WorkflowState<TContext>\n\tlet traverser: GraphTraverser\n\tconst history: string[] = []\n\n\tconst orchestrator = new StepByStepOrchestrator()\n\tconst executionId = globalThis.crypto?.randomUUID()\n\tconst nodeRegistry = new Map([...runtime.registry, ...functionRegistry])\n\n\tconst initialize = () => {\n\t\tstate = new WorkflowState<TContext>(_initialState)\n\t\ttraverser = new GraphTraverser(_initialBlueprint)\n\t\thistory.length = 0\n\t}\n\n\tinitialize()\n\n\tconst stepper: IWorkflowStepper<TContext> = {\n\t\tget state() {\n\t\t\treturn state\n\t\t},\n\t\tget traverser() {\n\t\t\treturn traverser\n\t\t},\n\t\tisDone() {\n\t\t\treturn !traverser.hasMoreWork() && !state.isAwaiting()\n\t\t},\n\t\treset() {\n\t\t\tinitialize()\n\t\t},\n\t\tasync prev() {\n\t\t\tconst previousStateJson = history.pop()\n\t\t\tif (!previousStateJson) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst previousStateData = runtime.serializer.deserialize(previousStateJson) as Partial<TContext>\n\n\t\t\tstate = new WorkflowState(previousStateData)\n\t\t\ttraverser = GraphTraverser.fromState(_initialBlueprint, state)\n\n\t\t\treturn state.toResult(runtime.serializer)\n\t\t},\n\t\tasync next(options: { signal?: AbortSignal; concurrency?: number } = {}) {\n\t\t\tif (stepper.isDone()) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst serializedContext = (await state.toResult(runtime.serializer)).serializedContext\n\t\t\thistory.push(serializedContext)\n\n\t\t\tconst executionContext = new ExecutionContext(\n\t\t\t\t_initialBlueprint,\n\t\t\t\tstate,\n\t\t\t\tnodeRegistry,\n\t\t\t\texecutionId,\n\t\t\t\truntime,\n\t\t\t\t{\n\t\t\t\t\tlogger: runtime.logger,\n\t\t\t\t\teventBus: runtime.eventBus,\n\t\t\t\t\tserializer: runtime.serializer,\n\t\t\t\t\tevaluator: runtime.evaluator,\n\t\t\t\t\tmiddleware: runtime.middleware,\n\t\t\t\t\tdependencies: runtime.dependencies,\n\t\t\t\t},\n\t\t\t\toptions.signal,\n\t\t\t\toptions.concurrency,\n\t\t\t)\n\t\t\treturn orchestrator.run(executionContext, traverser)\n\t\t},\n\t}\n\n\treturn stepper\n}\n"]}
@@ -3,11 +3,14 @@ import { BaseNode } from './chunk-LNK7LZER.js';
3
3
  // src/nodes/wait.ts
4
4
  var WaitNode = class extends BaseNode {
5
5
  async exec(_prepResult, context) {
6
- context.dependencies.workflowState.markAsAwaiting(this.nodeId ?? "");
6
+ context.dependencies.workflowState.markAsAwaiting(this.nodeId ?? "", {
7
+ reason: "external_event"
8
+ // params: this.params // NOTE: can add more details if needed in the future
9
+ });
7
10
  return { output: void 0 };
8
11
  }
9
12
  };
10
13
 
11
14
  export { WaitNode };
12
- //# sourceMappingURL=chunk-CD3Q4N6V.js.map
13
- //# sourceMappingURL=chunk-CD3Q4N6V.js.map
15
+ //# sourceMappingURL=chunk-GVF7GQXQ.js.map
16
+ //# sourceMappingURL=chunk-GVF7GQXQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/nodes/wait.ts"],"names":[],"mappings":";;;AAGO,IAAM,QAAA,GAAN,cAAuB,QAAA,CAAS;AAAA,EACtC,MAAM,IAAA,CACL,WAAA,EACA,OAAA,EACqC;AACrC,IAAA,OAAA,CAAQ,YAAA,CAAa,aAAA,CAAc,cAAA,CAAe,IAAA,CAAK,UAAU,EAAA,EAAI;AAAA,MACpE,MAAA,EAAQ;AAAA;AAAA,KAER,CAAA;AACD,IAAA,OAAO,EAAE,QAAQ,MAAA,EAAU;AAAA,EAC5B;AACD","file":"chunk-GVF7GQXQ.js","sourcesContent":["import { BaseNode } from '../node'\nimport type { NodeContext, NodeResult } from '../types'\n\nexport class WaitNode extends BaseNode {\n\tasync exec(\n\t\t_prepResult: any,\n\t\tcontext: NodeContext<Record<string, any>, any, any>,\n\t): Promise<Omit<NodeResult, 'error'>> {\n\t\tcontext.dependencies.workflowState.markAsAwaiting(this.nodeId ?? '', {\n\t\t\treason: 'external_event',\n\t\t\t// params: this.params // NOTE: can add more details if needed in the future\n\t\t})\n\t\treturn { output: undefined }\n\t}\n}\n"]}
@@ -1,5 +1,6 @@
1
- import { FlowRuntime } from './chunk-IB2BISIC.js';
1
+ import { FlowRuntime } from './chunk-CHG6O6JX.js';
2
2
  import { analyzeBlueprint } from './chunk-233SESC2.js';
3
+ import { ConsoleLogger } from './chunk-4PELJWF7.js';
3
4
  import { JsonSerializer } from './chunk-CYHZ2YVH.js';
4
5
 
5
6
  // src/runtime/adapter.ts
@@ -7,17 +8,19 @@ var BaseDistributedAdapter = class {
7
8
  runtime;
8
9
  store;
9
10
  serializer;
11
+ logger;
10
12
  constructor(options) {
11
13
  this.runtime = new FlowRuntime(options.runtimeOptions);
12
14
  this.store = options.coordinationStore;
13
15
  this.serializer = options.runtimeOptions.serializer || new JsonSerializer();
14
- console.log("[Adapter] BaseDistributedAdapter initialized.");
16
+ this.logger = options.runtimeOptions.logger || new ConsoleLogger();
17
+ this.logger.info("[Adapter] BaseDistributedAdapter initialized.");
15
18
  }
16
19
  /**
17
20
  * Starts the worker, which begins listening for and processing jobs from the queue.
18
21
  */
19
22
  start() {
20
- console.log("[Adapter] Starting worker...");
23
+ this.logger.info("[Adapter] Starting worker...");
21
24
  this.processJobs(this.handleJob.bind(this));
22
25
  }
23
26
  /**
@@ -35,7 +38,7 @@ var BaseDistributedAdapter = class {
35
38
  const blueprint = this.runtime.options.blueprints?.[blueprintId];
36
39
  if (!blueprint) {
37
40
  const reason = `Blueprint with ID '${blueprintId}' not found in the worker's runtime registry.`;
38
- console.error(`[Adapter] FATAL: ${reason}`);
41
+ this.logger.error(`[Adapter] FATAL: ${reason}`);
39
42
  await this.publishFinalResult(runId, { status: "failed", reason });
40
43
  return;
41
44
  }
@@ -51,7 +54,7 @@ var BaseDistributedAdapter = class {
51
54
  markFallbackExecuted: () => {
52
55
  },
53
56
  addError: (nodeId2, error) => {
54
- console.error(`[Adapter] Error in node ${nodeId2}:`, error);
57
+ this.logger.error(`[Adapter] Error in node ${nodeId2}:`, error);
55
58
  }
56
59
  };
57
60
  try {
@@ -60,12 +63,16 @@ var BaseDistributedAdapter = class {
60
63
  const analysis = analyzeBlueprint(blueprint);
61
64
  const isTerminalNode = analysis.terminalNodeIds.includes(nodeId);
62
65
  if (isTerminalNode) {
63
- const completedNodes = new Set(
64
- Object.keys(await context.toJSON()).filter((k) => blueprint.nodes.some((n) => n.id === k))
65
- );
66
+ const allContextKeys = Object.keys(await context.toJSON());
67
+ const completedNodes = /* @__PURE__ */ new Set();
68
+ for (const key of allContextKeys) {
69
+ if (key.startsWith("_outputs.")) {
70
+ completedNodes.add(key.substring("_outputs.".length));
71
+ }
72
+ }
66
73
  const allTerminalNodesCompleted = analysis.terminalNodeIds.every((terminalId) => completedNodes.has(terminalId));
67
74
  if (allTerminalNodesCompleted) {
68
- console.log(`[Adapter] All terminal nodes completed for Run ID: ${runId}. Declaring workflow complete.`);
75
+ this.logger.info(`[Adapter] All terminal nodes completed for Run ID: ${runId}. Declaring workflow complete.`);
69
76
  const finalContext = await context.toJSON();
70
77
  const finalResult = {
71
78
  context: finalContext,
@@ -78,14 +85,14 @@ var BaseDistributedAdapter = class {
78
85
  });
79
86
  return;
80
87
  } else {
81
- console.log(
88
+ this.logger.info(
82
89
  `[Adapter] Terminal node '${nodeId}' completed for Run ID '${runId}', but other terminal nodes are still running.`
83
90
  );
84
91
  }
85
92
  }
86
93
  const nextNodes = await this.runtime.determineNextNodes(blueprint, nodeId, result, context, runId);
87
94
  if (nextNodes.length === 0 && !isTerminalNode) {
88
- console.log(
95
+ this.logger.info(
89
96
  `[Adapter] Non-terminal node '${nodeId}' reached end of branch for Run ID '${runId}'. This branch will now terminate.`
90
97
  );
91
98
  return;
@@ -94,15 +101,15 @@ var BaseDistributedAdapter = class {
94
101
  await this.runtime.applyEdgeTransform(edge, result, nextNodeDef, context);
95
102
  const isReady = await this.isReadyForFanIn(runId, blueprint, nextNodeDef.id);
96
103
  if (isReady) {
97
- console.log(`[Adapter] Node '${nextNodeDef.id}' is ready. Enqueuing job.`);
104
+ this.logger.info(`[Adapter] Node '${nextNodeDef.id}' is ready. Enqueuing job.`);
98
105
  await this.enqueueJob({ runId, blueprintId, nodeId: nextNodeDef.id });
99
106
  } else {
100
- console.log(`[Adapter] Node '${nextNodeDef.id}' is waiting for other predecessors to complete.`);
107
+ this.logger.info(`[Adapter] Node '${nextNodeDef.id}' is waiting for other predecessors to complete.`);
101
108
  }
102
109
  }
103
110
  } catch (error) {
104
111
  const reason = error.message || "Unknown execution error";
105
- console.error(`[Adapter] FATAL: Job for node '${nodeId}' failed for Run ID '${runId}': ${reason}`);
112
+ this.logger.error(`[Adapter] FATAL: Job for node '${nodeId}' failed for Run ID '${runId}': ${reason}`);
106
113
  await this.publishFinalResult(runId, { status: "failed", reason });
107
114
  await this.writePoisonPillForSuccessors(runId, blueprint, nodeId);
108
115
  }
@@ -121,9 +128,9 @@ var BaseDistributedAdapter = class {
121
128
  return true;
122
129
  }
123
130
  const poisonKey = `flowcraft:fanin:poison:${runId}:${targetNodeId}`;
124
- const isPoisoned = !await this.store.setIfNotExist(poisonKey, "poisoned", 3600);
131
+ const isPoisoned = await this.store.get(poisonKey);
125
132
  if (isPoisoned) {
126
- console.log(`[Adapter] Node '${targetNodeId}' is poisoned due to failed predecessor. Failing immediately.`);
133
+ this.logger.info(`[Adapter] Node '${targetNodeId}' is poisoned due to failed predecessor. Failing immediately.`);
127
134
  throw new Error(`Node '${targetNodeId}' failed due to poisoned predecessor in run '${runId}'`);
128
135
  }
129
136
  if (joinStrategy === "any") {
@@ -133,7 +140,9 @@ var BaseDistributedAdapter = class {
133
140
  const cancelKey = `flowcraft:fanin:cancel:${runId}:${targetNodeId}`;
134
141
  const isCancelled = !await this.store.setIfNotExist(cancelKey, "cancelled", 3600);
135
142
  if (isCancelled) {
136
- console.log(`[Adapter] Node '${targetNodeId}' is cancelled due to failed predecessor. Failing immediately.`);
143
+ this.logger.info(
144
+ `[Adapter] Node '${targetNodeId}' is cancelled due to failed predecessor. Failing immediately.`
145
+ );
137
146
  throw new Error(`Node '${targetNodeId}' failed due to cancelled predecessor in run '${runId}'`);
138
147
  }
139
148
  return false;
@@ -175,30 +184,41 @@ var BaseDistributedAdapter = class {
175
184
  throw new Error(`Cannot reconcile runId '${runId}': Blueprint with ID '${blueprintId}' not found.`);
176
185
  }
177
186
  const state = await context.toJSON();
178
- const completedNodes = new Set(Object.keys(state).filter((k) => blueprint.nodes.some((n) => n.id === k)));
187
+ const completedNodes = /* @__PURE__ */ new Set();
188
+ for (const key of Object.keys(state)) {
189
+ if (key.startsWith("_outputs.")) {
190
+ completedNodes.add(key.substring("_outputs.".length));
191
+ }
192
+ }
179
193
  const frontier = this.calculateResumedFrontier(blueprint, completedNodes);
180
194
  const enqueuedNodes = /* @__PURE__ */ new Set();
181
195
  for (const nodeId of frontier) {
182
196
  const nodeDef = blueprint.nodes.find((n) => n.id === nodeId);
183
197
  const joinStrategy = nodeDef?.config?.joinStrategy || "all";
198
+ const poisonKey = `flowcraft:fanin:poison:${runId}:${nodeId}`;
199
+ const isPoisoned = await this.store.get(poisonKey);
200
+ if (isPoisoned) {
201
+ this.logger.info(`[Adapter] Reconciling: Node '${nodeId}' is poisoned, skipping.`, { runId });
202
+ continue;
203
+ }
184
204
  let shouldEnqueue = false;
185
205
  if (joinStrategy === "any") {
186
206
  const lockKey = `flowcraft:joinlock:${runId}:${nodeId}`;
187
207
  if (await this.store.setIfNotExist(lockKey, "locked-by-reconcile", 3600)) {
188
208
  shouldEnqueue = true;
189
209
  } else {
190
- console.log(`[Adapter] Reconciling: Node '${nodeId}' is an 'any' join and is already locked.`, { runId });
210
+ this.logger.info(`[Adapter] Reconciling: Node '${nodeId}' is an 'any' join and is already locked.`, { runId });
191
211
  }
192
212
  } else {
193
213
  const lockKey = `flowcraft:nodelock:${runId}:${nodeId}`;
194
214
  if (await this.store.setIfNotExist(lockKey, "locked", 120)) {
195
215
  shouldEnqueue = true;
196
216
  } else {
197
- console.log(`[Adapter] Reconciling: Node '${nodeId}' is already locked.`, { runId });
217
+ this.logger.info(`[Adapter] Reconciling: Node '${nodeId}' is already locked.`, { runId });
198
218
  }
199
219
  }
200
220
  if (shouldEnqueue) {
201
- console.log(`[Adapter] Reconciling: Enqueuing ready job for node '${nodeId}'`, { runId });
221
+ this.logger.info(`[Adapter] Reconciling: Enqueuing ready job for node '${nodeId}'`, { runId });
202
222
  await this.enqueueJob({ runId, blueprintId: blueprint.id, nodeId });
203
223
  enqueuedNodes.add(nodeId);
204
224
  }
@@ -243,13 +263,13 @@ var BaseDistributedAdapter = class {
243
263
  if (joinStrategy === "all") {
244
264
  const poisonKey = `flowcraft:fanin:poison:${runId}:${successor.id}`;
245
265
  await this.store.setIfNotExist(poisonKey, "poisoned", 3600);
246
- console.log(
266
+ this.logger.info(
247
267
  `[Adapter] Wrote poison pill for 'all' join node '${successor.id}' due to failed predecessor '${failedNodeId}'`
248
268
  );
249
269
  } else if (joinStrategy === "any") {
250
270
  const cancelKey = `flowcraft:fanin:cancel:${runId}:${successor.id}`;
251
271
  await this.store.setIfNotExist(cancelKey, "cancelled", 3600);
252
- console.log(
272
+ this.logger.info(
253
273
  `[Adapter] Wrote cancellation pill for 'any' join node '${successor.id}' due to failed predecessor '${failedNodeId}'`
254
274
  );
255
275
  }
@@ -259,5 +279,5 @@ var BaseDistributedAdapter = class {
259
279
  };
260
280
 
261
281
  export { BaseDistributedAdapter };
262
- //# sourceMappingURL=chunk-6INWPSZT.js.map
263
- //# sourceMappingURL=chunk-6INWPSZT.js.map
282
+ //# sourceMappingURL=chunk-J3HZD5ES.js.map
283
+ //# sourceMappingURL=chunk-J3HZD5ES.js.map