flowcraft 2.6.1 → 2.7.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 (124) hide show
  1. package/dist/adapters/index.d.ts +4 -0
  2. package/dist/adapters/index.js +4 -0
  3. package/dist/adapters/index.js.map +1 -0
  4. package/dist/adapters/persistent-event-bus.d.ts +69 -0
  5. package/dist/adapters/persistent-event-bus.js +3 -0
  6. package/dist/adapters/persistent-event-bus.js.map +1 -0
  7. package/dist/analysis.d.ts +1 -1
  8. package/dist/chunk-3Y5O5EGB.js +3 -0
  9. package/dist/{chunk-NVJ3ZO3P.js.map → chunk-3Y5O5EGB.js.map} +1 -1
  10. package/dist/{chunk-BTCZU2DJ.js → chunk-4TVWI6Y6.js} +4 -4
  11. package/dist/{chunk-BTCZU2DJ.js.map → chunk-4TVWI6Y6.js.map} +1 -1
  12. package/dist/{chunk-6X5BERRF.js → chunk-6RKHCJUU.js} +2 -2
  13. package/dist/{chunk-6X5BERRF.js.map → chunk-6RKHCJUU.js.map} +1 -1
  14. package/dist/{chunk-MUYLRTSR.js → chunk-7EBKWATZ.js} +9 -5
  15. package/dist/chunk-7EBKWATZ.js.map +1 -0
  16. package/dist/{chunk-IWTFVGMK.js → chunk-AKDL2ZX7.js} +2 -2
  17. package/dist/{chunk-IWTFVGMK.js.map → chunk-AKDL2ZX7.js.map} +1 -1
  18. package/dist/chunk-ASJYJ3NF.js +46 -0
  19. package/dist/chunk-ASJYJ3NF.js.map +1 -0
  20. package/dist/chunk-HFJXYY4E.js +3 -0
  21. package/dist/chunk-HFJXYY4E.js.map +1 -0
  22. package/dist/{chunk-VB7VNXR7.js → chunk-HXSK5P2X.js} +11 -5
  23. package/dist/chunk-HXSK5P2X.js.map +1 -0
  24. package/dist/{chunk-2YLGY3R2.js → chunk-K6ID3GRG.js} +7 -7
  25. package/dist/chunk-K6ID3GRG.js.map +1 -0
  26. package/dist/{chunk-QSQ2BSGG.js → chunk-LU5SLE3P.js} +4 -4
  27. package/dist/{chunk-QSQ2BSGG.js.map → chunk-LU5SLE3P.js.map} +1 -1
  28. package/dist/{chunk-N4NLAIEN.js → chunk-LWN7HOD3.js} +4 -3
  29. package/dist/chunk-LWN7HOD3.js.map +1 -0
  30. package/dist/{chunk-SF5GQHUU.js → chunk-N63S5NEG.js} +10 -3
  31. package/dist/chunk-N63S5NEG.js.map +1 -0
  32. package/dist/{chunk-C3ZT7FNO.js → chunk-RAZWRNAJ.js} +5 -5
  33. package/dist/chunk-RAZWRNAJ.js.map +1 -0
  34. package/dist/{chunk-NQORJ53O.js → chunk-RF5EYEO6.js} +4 -4
  35. package/dist/{chunk-NQORJ53O.js.map → chunk-RF5EYEO6.js.map} +1 -1
  36. package/dist/chunk-TKSSRS5U.js +39 -0
  37. package/dist/chunk-TKSSRS5U.js.map +1 -0
  38. package/dist/{chunk-3YV6X6VQ.js → chunk-TTOS7NW3.js} +5 -5
  39. package/dist/chunk-TTOS7NW3.js.map +1 -0
  40. package/dist/chunk-UNORA7EM.js +103 -0
  41. package/dist/chunk-UNORA7EM.js.map +1 -0
  42. package/dist/{chunk-34LDT5EG.js → chunk-VDVUF25G.js} +65 -16
  43. package/dist/chunk-VDVUF25G.js.map +1 -0
  44. package/dist/{chunk-5BOUGXZO.js → chunk-VSKDQVCG.js} +16 -4
  45. package/dist/chunk-VSKDQVCG.js.map +1 -0
  46. package/dist/{chunk-O3QJFRXS.js → chunk-W4IAXDO4.js} +28 -6
  47. package/dist/chunk-W4IAXDO4.js.map +1 -0
  48. package/dist/{chunk-XDI4TJHA.js → chunk-ZETQCNEF.js} +49 -5
  49. package/dist/chunk-ZETQCNEF.js.map +1 -0
  50. package/dist/container-factory.d.ts +1 -1
  51. package/dist/container-factory.js +7 -7
  52. package/dist/context.d.ts +15 -2
  53. package/dist/context.js +1 -1
  54. package/dist/error-mapper.d.ts +1 -1
  55. package/dist/evaluator.d.ts +1 -1
  56. package/dist/flow.d.ts +3 -3
  57. package/dist/flow.js +1 -1
  58. package/dist/index.d.ts +3 -1
  59. package/dist/index.js +21 -18
  60. package/dist/linter.d.ts +1 -1
  61. package/dist/logger.d.ts +1 -1
  62. package/dist/node.d.ts +1 -1
  63. package/dist/nodes/batch-gather.d.ts +1 -1
  64. package/dist/nodes/batch-scatter.d.ts +1 -1
  65. package/dist/nodes/sleep.d.ts +1 -1
  66. package/dist/nodes/subflow.d.ts +1 -1
  67. package/dist/nodes/subflow.js +4 -4
  68. package/dist/nodes/wait.d.ts +1 -1
  69. package/dist/nodes/webhook.d.ts +1 -1
  70. package/dist/runtime/adapter.d.ts +3 -1
  71. package/dist/runtime/adapter.js +15 -15
  72. package/dist/runtime/execution-context.d.ts +1 -1
  73. package/dist/runtime/execution-context.js +3 -3
  74. package/dist/runtime/executors.d.ts +1 -1
  75. package/dist/runtime/index.d.ts +2 -1
  76. package/dist/runtime/index.js +17 -16
  77. package/dist/runtime/node-executor-factory.d.ts +1 -1
  78. package/dist/runtime/orchestrator.d.ts +1 -1
  79. package/dist/runtime/orchestrator.js +5 -5
  80. package/dist/runtime/orchestrators/replay.d.ts +45 -0
  81. package/dist/runtime/orchestrators/replay.js +3 -0
  82. package/dist/runtime/orchestrators/replay.js.map +1 -0
  83. package/dist/runtime/orchestrators/step-by-step.d.ts +1 -1
  84. package/dist/runtime/orchestrators/step-by-step.js +2 -2
  85. package/dist/runtime/orchestrators/utils.d.ts +1 -1
  86. package/dist/runtime/orchestrators/utils.js +1 -1
  87. package/dist/runtime/runtime.d.ts +1 -1
  88. package/dist/runtime/runtime.js +14 -14
  89. package/dist/runtime/scheduler.d.ts +1 -1
  90. package/dist/runtime/state.d.ts +1 -1
  91. package/dist/runtime/state.js +2 -2
  92. package/dist/runtime/traverser.d.ts +1 -1
  93. package/dist/runtime/types.d.ts +1 -1
  94. package/dist/runtime/workflow-logic-handler.d.ts +2 -2
  95. package/dist/runtime/workflow-logic-handler.js +2 -2
  96. package/dist/sanitizer.d.ts +1 -2
  97. package/dist/sanitizer.js +1 -1
  98. package/dist/serializer.d.ts +1 -1
  99. package/dist/serializer.js +1 -1
  100. package/dist/testing/event-logger.d.ts +1 -1
  101. package/dist/testing/event-logger.js +1 -1
  102. package/dist/testing/index.d.ts +2 -1
  103. package/dist/testing/index.js +23 -20
  104. package/dist/testing/run-with-trace.d.ts +1 -1
  105. package/dist/testing/run-with-trace.js +19 -18
  106. package/dist/testing/stepper.d.ts +1 -1
  107. package/dist/testing/stepper.js +6 -6
  108. package/dist/{types-Cv5JcMwI.d.ts → types-D-dVKe4_.d.ts} +48 -5
  109. package/dist/types.d.ts +1 -1
  110. package/package.json +1 -1
  111. package/dist/chunk-2YLGY3R2.js.map +0 -1
  112. package/dist/chunk-34LDT5EG.js.map +0 -1
  113. package/dist/chunk-3YV6X6VQ.js.map +0 -1
  114. package/dist/chunk-5BOUGXZO.js.map +0 -1
  115. package/dist/chunk-C3ZT7FNO.js.map +0 -1
  116. package/dist/chunk-HLN72CCU.js +0 -43
  117. package/dist/chunk-HLN72CCU.js.map +0 -1
  118. package/dist/chunk-MUYLRTSR.js.map +0 -1
  119. package/dist/chunk-N4NLAIEN.js.map +0 -1
  120. package/dist/chunk-NVJ3ZO3P.js +0 -3
  121. package/dist/chunk-O3QJFRXS.js.map +0 -1
  122. package/dist/chunk-SF5GQHUU.js.map +0 -1
  123. package/dist/chunk-VB7VNXR7.js.map +0 -1
  124. package/dist/chunk-XDI4TJHA.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { WorkflowState } from './chunk-5BOUGXZO.js';
1
+ import { WorkflowState } from './chunk-VSKDQVCG.js';
2
2
 
3
3
  // src/runtime/execution-context.ts
4
4
  var ExecutionContext = class _ExecutionContext {
@@ -11,6 +11,7 @@ var ExecutionContext = class _ExecutionContext {
11
11
  this.services = services;
12
12
  this.signal = signal;
13
13
  this.concurrency = concurrency;
14
+ this.state.setEventEmitter(this.services.eventBus, this.executionId);
14
15
  }
15
16
  createForSubflow(subBlueprint, initialSubState) {
16
17
  const subState = new WorkflowState(initialSubState);
@@ -28,5 +29,5 @@ var ExecutionContext = class _ExecutionContext {
28
29
  };
29
30
 
30
31
  export { ExecutionContext };
31
- //# sourceMappingURL=chunk-N4NLAIEN.js.map
32
- //# sourceMappingURL=chunk-N4NLAIEN.js.map
32
+ //# sourceMappingURL=chunk-LWN7HOD3.js.map
33
+ //# sourceMappingURL=chunk-LWN7HOD3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/execution-context.ts"],"names":[],"mappings":";;;AAkBO,IAAM,gBAAA,GAAN,MAAM,iBAAA,CAAkG;AAAA,EAC9G,WAAA,CACiB,WACA,KAAA,EACA,YAAA,EACA,aACA,OAAA,EACA,QAAA,EAQA,QACA,WAAA,EACf;AAfe,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AACA,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAQA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAEhB,IAAA,IAAA,CAAK,MAAM,eAAA,CAAgB,IAAA,CAAK,QAAA,CAAS,QAAA,EAAU,KAAK,WAAW,CAAA;AAAA,EACpE;AAAA,EAEO,gBAAA,CACN,cACA,eAAA,EAC4C;AAC5C,IAAA,MAAM,QAAA,GAAW,IAAI,aAAA,CAAwB,eAAe,CAAA;AAC5D,IAAA,OAAO,IAAI,iBAAA;AAAA,MACV,YAAA;AAAA,MACA,QAAA;AAAA,MACA,IAAA,CAAK,YAAA;AAAA,MACL,IAAA,CAAK,WAAA;AAAA,MACL,IAAA,CAAK,OAAA;AAAA,MACL,IAAA,CAAK,QAAA;AAAA,MACL,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACN;AAAA,EACD;AACD","file":"chunk-LWN7HOD3.js","sourcesContent":["import type {\n\tIEvaluator,\n\tIEventBus,\n\tILogger,\n\tISerializer,\n\tMiddleware,\n\tNodeClass,\n\tNodeFunction,\n\tRuntimeDependencies,\n\tWorkflowBlueprint,\n} from '../types'\nimport type { FlowRuntime } from './runtime'\nimport { WorkflowState } from './state'\n\n/**\n * A container for all state and dependencies of a single workflow execution.\n * This object is created once per `run` and passed through the execution stack.\n */\nexport class ExecutionContext<TContext extends Record<string, any>, TDependencies extends RuntimeDependencies> {\n\tconstructor(\n\t\tpublic readonly blueprint: WorkflowBlueprint,\n\t\tpublic readonly state: WorkflowState<TContext>,\n\t\tpublic readonly nodeRegistry: Map<string, NodeFunction | NodeClass>,\n\t\tpublic readonly executionId: string,\n\t\tpublic readonly runtime: FlowRuntime<TContext, TDependencies>, // A reference back to the runtime for orchestrating subflows\n\t\tpublic readonly services: {\n\t\t\tlogger: ILogger\n\t\t\teventBus: IEventBus\n\t\t\tserializer: ISerializer\n\t\t\tevaluator: IEvaluator\n\t\t\tmiddleware: Middleware[]\n\t\t\tdependencies: TDependencies\n\t\t},\n\t\tpublic readonly signal?: AbortSignal,\n\t\tpublic readonly concurrency?: number,\n\t) {\n\t\tthis.state.setEventEmitter(this.services.eventBus, this.executionId)\n\t}\n\n\tpublic createForSubflow(\n\t\tsubBlueprint: WorkflowBlueprint,\n\t\tinitialSubState: Partial<TContext>,\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.nodeRegistry,\n\t\t\tthis.executionId,\n\t\t\tthis.runtime,\n\t\t\tthis.services,\n\t\t\tthis.signal,\n\t\t\tthis.concurrency,\n\t\t)\n\t}\n}\n"]}
@@ -65,7 +65,14 @@ async function processResults(settledResults, traverser, state, runtime, _bluepr
65
65
  );
66
66
  const finalMatched = loopControllerMatch ? [loopControllerMatch] : matched;
67
67
  for (const { node, edge } of finalMatched) {
68
- await runtime.applyEdgeTransform(edge, result, node, state.getContext(), traverser.getAllPredecessors());
68
+ await runtime.applyEdgeTransform(
69
+ edge,
70
+ result,
71
+ node,
72
+ state.getContext(),
73
+ traverser.getAllPredecessors(),
74
+ executionId
75
+ );
69
76
  }
70
77
  traverser.markNodeCompleted(
71
78
  nodeId,
@@ -96,5 +103,5 @@ async function processResults(settledResults, traverser, state, runtime, _bluepr
96
103
  }
97
104
 
98
105
  export { executeBatch, processResults };
99
- //# sourceMappingURL=chunk-SF5GQHUU.js.map
100
- //# sourceMappingURL=chunk-SF5GQHUU.js.map
106
+ //# sourceMappingURL=chunk-N63S5NEG.js.map
107
+ //# sourceMappingURL=chunk-N63S5NEG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/orchestrators/utils.ts"],"names":["nodeId"],"mappings":"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","file":"chunk-N63S5NEG.js","sourcesContent":["import { FlowcraftError } from '../../errors'\nimport type { NodeDefinition, WorkflowBlueprint } from '../../types'\nimport type { NodeExecutionResult } from '../executors'\nimport type { WorkflowState } from '../state'\nimport type { GraphTraverser } from '../traverser'\n\nexport async function executeBatch(\n\treadyNodes: Array<{ nodeId: string; nodeDef: any }>,\n\tblueprint: WorkflowBlueprint,\n\tstate: WorkflowState<any>,\n\texecutorFactory: (nodeId: string) => any,\n\truntime: any,\n\tmaxConcurrency?: number,\n): Promise<\n\tArray<\n\t\t| { status: 'fulfilled'; value: { nodeId: string; executionResult: NodeExecutionResult } }\n\t\t| { status: 'rejected'; reason: { nodeId: string; error: unknown } }\n\t>\n> {\n\tconst concurrency = maxConcurrency || readyNodes.length\n\tconst results: Array<\n\t\t| { status: 'fulfilled'; value: { nodeId: string; executionResult: NodeExecutionResult } }\n\t\t| { status: 'rejected'; reason: { nodeId: string; error: unknown } }\n\t> = []\n\n\tfor (let i = 0; i < readyNodes.length; i += concurrency) {\n\t\tconst batch = readyNodes.slice(i, i + concurrency)\n\t\tconst batchPromises = batch.map(async ({ nodeId }) => {\n\t\t\ttry {\n\t\t\t\tconst executor = executorFactory(nodeId)\n\t\t\t\tif (!executor) throw new Error(`No executor for node ${nodeId}`)\n\t\t\t\tconst executionResult = await executor.execute(\n\t\t\t\t\tawait runtime.resolveNodeInput(nodeId, blueprint, state.getContext()),\n\t\t\t\t)\n\t\t\t\tresults.push({\n\t\t\t\t\tstatus: 'fulfilled' as const,\n\t\t\t\t\tvalue: { nodeId, executionResult },\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tresults.push({\n\t\t\t\t\tstatus: 'rejected' as const,\n\t\t\t\t\treason: { nodeId, error },\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\n\t\tawait Promise.all(batchPromises)\n\t}\n\n\treturn results\n}\n\nexport async function processResults(\n\tsettledResults: Array<\n\t\t| { status: 'fulfilled'; value: { nodeId: string; executionResult: NodeExecutionResult } }\n\t\t| { status: 'rejected'; reason: { nodeId: string; error: unknown } }\n\t>,\n\ttraverser: GraphTraverser,\n\tstate: WorkflowState<any>,\n\truntime: any,\n\t_blueprint: WorkflowBlueprint,\n\texecutionId?: string,\n): Promise<void> {\n\tfor (const promiseResult of settledResults) {\n\t\tif (promiseResult.status === 'rejected') {\n\t\t\tconst { nodeId, error } = promiseResult.reason\n\t\t\tif (error instanceof FlowcraftError && error.message.includes('cancelled')) {\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\tstate.addError(nodeId, error as Error)\n\t\t\tcontinue\n\t\t}\n\n\t\tconst { nodeId, executionResult } = promiseResult.value\n\n\t\tif (executionResult.status === 'success') {\n\t\t\tconst result = executionResult.result\n\t\t\tif (result) {\n\t\t\t\tstate.addCompletedNode(nodeId, result.output)\n\t\t\t\tif (result._fallbackExecuted) {\n\t\t\t\t\tstate.markFallbackExecuted()\n\t\t\t\t}\n\n\t\t\t\tif (result.dynamicNodes && result.dynamicNodes.length > 0) {\n\t\t\t\t\tconst gatherNodeId = result.output?.gatherNodeId\n\t\t\t\t\tfor (const dynamicNode of result.dynamicNodes) {\n\t\t\t\t\t\ttraverser.addDynamicNode(dynamicNode.id, dynamicNode, nodeId, gatherNodeId)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst matched = await runtime.determineNextNodes(\n\t\t\t\ttraverser.getDynamicBlueprint(),\n\t\t\t\tnodeId,\n\t\t\t\tresult,\n\t\t\t\tstate.getContext(),\n\t\t\t\texecutionId,\n\t\t\t)\n\n\t\t\tconst loopControllerMatch = matched.find(\n\t\t\t\t(m: { node: NodeDefinition; edge: any }) => m.node.uses === 'loop-controller',\n\t\t\t)\n\t\t\tconst finalMatched = loopControllerMatch ? [loopControllerMatch] : matched\n\n\t\t\tfor (const { node, edge } of finalMatched) {\n\t\t\t\tawait runtime.applyEdgeTransform(\n\t\t\t\t\tedge,\n\t\t\t\t\tresult,\n\t\t\t\t\tnode,\n\t\t\t\t\tstate.getContext(),\n\t\t\t\t\ttraverser.getAllPredecessors(),\n\t\t\t\t\texecutionId,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\ttraverser.markNodeCompleted(\n\t\t\t\tnodeId,\n\t\t\t\tresult,\n\t\t\t\tfinalMatched.map((m: { node: NodeDefinition; edge: any }) => m.node),\n\t\t\t)\n\t\t} else if (executionResult.status === 'failed_with_fallback') {\n\t\t\tconst { fallbackNodeId, error } = executionResult\n\t\t\tconst blueprint = traverser.getDynamicBlueprint()\n\t\t\tconst fallbackNodeDef = blueprint.nodes.find((n) => n.id === fallbackNodeId)\n\n\t\t\tif (!fallbackNodeDef) {\n\t\t\t\tconst notFoundError = new FlowcraftError(`Fallback node '${fallbackNodeId}' not found in blueprint.`, {\n\t\t\t\t\tnodeId,\n\t\t\t\t\tcause: error,\n\t\t\t\t})\n\t\t\t\tstate.addError(nodeId, notFoundError)\n\t\t\t} else {\n\t\t\t\tstate.addCompletedNode(nodeId, null)\n\t\t\t\tstate.markFallbackExecuted()\n\n\t\t\t\ttraverser.markNodeCompleted(nodeId, { action: 'fallback', output: null, _fallbackExecuted: true }, [\n\t\t\t\t\tfallbackNodeDef,\n\t\t\t\t])\n\t\t\t}\n\t\t} else {\n\t\t\tstate.addError(nodeId, executionResult.error)\n\t\t}\n\t}\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { executeBatch, processResults } from './chunk-SF5GQHUU.js';
1
+ import { executeBatch, processResults } from './chunk-N63S5NEG.js';
2
2
  import { FlowcraftError } from './chunk-BCRWXTWX.js';
3
3
 
4
4
  // src/runtime/orchestrators/step-by-step.ts
@@ -15,7 +15,7 @@ var StepByStepOrchestrator = class {
15
15
  if (!traverser.hasMoreWork()) {
16
16
  const isTraversalComplete2 = !traverser.hasMoreWork();
17
17
  const status2 = context.state.getStatus(isTraversalComplete2);
18
- const result2 = await context.state.toResult(context.services.serializer);
18
+ const result2 = await context.state.toResult(context.services.serializer, context.executionId);
19
19
  result2.status = status2;
20
20
  return result2;
21
21
  }
@@ -43,12 +43,12 @@ var StepByStepOrchestrator = class {
43
43
  }
44
44
  const isTraversalComplete = !traverser.hasMoreWork();
45
45
  const status = context.state.getStatus(isTraversalComplete);
46
- const result = await context.state.toResult(context.services.serializer);
46
+ const result = await context.state.toResult(context.services.serializer, context.executionId);
47
47
  result.status = status;
48
48
  return result;
49
49
  }
50
50
  };
51
51
 
52
52
  export { StepByStepOrchestrator };
53
- //# sourceMappingURL=chunk-C3ZT7FNO.js.map
54
- //# sourceMappingURL=chunk-C3ZT7FNO.js.map
53
+ //# sourceMappingURL=chunk-RAZWRNAJ.js.map
54
+ //# sourceMappingURL=chunk-RAZWRNAJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/orchestrators/step-by-step.ts"],"names":["isTraversalComplete","status","result"],"mappings":";;;;AAeO,IAAM,yBAAN,MAAsD;AAAA,EAC5D,MAAa,GAAA,CAAI,OAAA,EAAqC,SAAA,EAAyD;AAC9G,IAAA,IAAI;AACH,MAAA,OAAA,CAAQ,QAAQ,cAAA,EAAe;AAAA,IAChC,SAAS,KAAA,EAAO;AACf,MAAA,IAAI,KAAA,YAAiB,YAAA,IAAgB,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AACjE,QAAA,MAAM,IAAI,cAAA,CAAe,oBAAA,EAAsB,EAAE,OAAA,EAAS,OAAO,CAAA;AAAA,MAClE;AACA,MAAA,MAAM,KAAA;AAAA,IACP;AAEA,IAAA,IAAI,CAAC,SAAA,CAAU,WAAA,EAAY,EAAG;AAC7B,MAAA,MAAMA,oBAAAA,GAAsB,CAAC,SAAA,CAAU,WAAA,EAAY;AACnD,MAAA,MAAMC,OAAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,SAAA,CAAUD,oBAAmB,CAAA;AAC1D,MAAA,MAAME,OAAAA,GAAS,MAAM,OAAA,CAAQ,KAAA,CAAM,SAAS,OAAA,CAAQ,QAAA,CAAS,UAAA,EAAY,OAAA,CAAQ,WAAW,CAAA;AAC5F,MAAAA,QAAO,MAAA,GAASD,OAAAA;AAChB,MAAA,OAAOC,OAAAA;AAAA,IACR;AAEA,IAAA,MAAM,aAAA,GAAgB,UAAU,aAAA,EAAc;AAC9C,IAAA,MAAM,cAAA,GAAiB,QAAQ,WAAA,GAAc,aAAA,CAAc,MAAM,CAAA,EAAG,OAAA,CAAQ,WAAW,CAAA,GAAI,aAAA;AAC3F,IAAA,MAAM,WAAA,GAAc,QAAQ,WAAA,GAAc,aAAA,CAAc,MAAM,OAAA,CAAQ,WAAW,IAAI,EAAC;AAEtF,IAAA,MAAM,iBAAiB,MAAM,YAAA;AAAA,MAC5B,cAAA;AAAA,MACA,UAAU,mBAAA,EAAoB;AAAA,MAC9B,OAAA,CAAQ,KAAA;AAAA,MACR,CAAC,MAAA,KAAmB,OAAA,CAAQ,OAAA,CAAQ,kBAAA,CAAmB,QAAQ,OAAO,CAAA;AAAA,MACtE,OAAA,CAAQ,OAAA;AAAA,MACR,OAAA,CAAQ;AAAA,KACT;AAEA,IAAA,MAAM,cAAA;AAAA,MACL,cAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA,CAAQ,KAAA;AAAA,MACR,OAAA,CAAQ,OAAA;AAAA,MACR,OAAA,CAAQ,SAAA;AAAA,MACR,OAAA,CAAQ;AAAA,KACT;AAEA,IAAA,KAAA,MAAW,EAAE,MAAA,EAAO,IAAK,WAAA,EAAa;AACrC,MAAA,SAAA,CAAU,cAAc,MAAM,CAAA;AAAA,IAC/B;AAEA,IAAA,MAAM,mBAAA,GAAsB,CAAC,SAAA,CAAU,WAAA,EAAY;AACnD,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,SAAA,CAAU,mBAAmB,CAAA;AAC1D,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,KAAA,CAAM,SAAS,OAAA,CAAQ,QAAA,CAAS,UAAA,EAAY,OAAA,CAAQ,WAAW,CAAA;AAC5F,IAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,IAAA,OAAO,MAAA;AAAA,EACR;AACD","file":"chunk-RAZWRNAJ.js","sourcesContent":["import { FlowcraftError } from '../../errors'\n\nimport type { WorkflowResult } from '../../types'\nimport type { ExecutionContext } from '../execution-context'\nimport type { GraphTraverser } from '../traverser'\nimport type { IOrchestrator } from '../types'\nimport { executeBatch, processResults } from './utils'\n\n/**\n * An orchestrator that executes only one \"tick\" or \"turn\" of the workflow.\n * It processes a single batch of ready nodes from the frontier and then returns,\n * allowing the caller to inspect the intermediate state before proceeding.\n *\n * Useful for debugging, testing, or building interactive tools.\n */\nexport class StepByStepOrchestrator implements IOrchestrator {\n\tpublic async run(context: ExecutionContext<any, any>, traverser: GraphTraverser): Promise<WorkflowResult<any>> {\n\t\ttry {\n\t\t\tcontext.signal?.throwIfAborted()\n\t\t} catch (error) {\n\t\t\tif (error instanceof DOMException && error.name === 'AbortError') {\n\t\t\t\tthrow new FlowcraftError('Workflow cancelled', { isFatal: false })\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\n\t\tif (!traverser.hasMoreWork()) {\n\t\t\tconst isTraversalComplete = !traverser.hasMoreWork()\n\t\t\tconst status = context.state.getStatus(isTraversalComplete)\n\t\t\tconst result = await context.state.toResult(context.services.serializer, context.executionId)\n\t\t\tresult.status = status\n\t\t\treturn result\n\t\t}\n\n\t\tconst allReadyNodes = traverser.getReadyNodes()\n\t\tconst nodesToExecute = context.concurrency ? allReadyNodes.slice(0, context.concurrency) : allReadyNodes\n\t\tconst nodesToSkip = context.concurrency ? allReadyNodes.slice(context.concurrency) : []\n\n\t\tconst settledResults = await executeBatch(\n\t\t\tnodesToExecute,\n\t\t\ttraverser.getDynamicBlueprint(),\n\t\t\tcontext.state,\n\t\t\t(nodeId: string) => context.runtime.getExecutorForNode(nodeId, context),\n\t\t\tcontext.runtime,\n\t\t\tcontext.concurrency,\n\t\t)\n\n\t\tawait processResults(\n\t\t\tsettledResults,\n\t\t\ttraverser,\n\t\t\tcontext.state,\n\t\t\tcontext.runtime,\n\t\t\tcontext.blueprint,\n\t\t\tcontext.executionId,\n\t\t)\n\n\t\tfor (const { nodeId } of nodesToSkip) {\n\t\t\ttraverser.addToFrontier(nodeId)\n\t\t}\n\n\t\tconst isTraversalComplete = !traverser.hasMoreWork()\n\t\tconst status = context.state.getStatus(isTraversalComplete)\n\t\tconst result = await context.state.toResult(context.services.serializer, context.executionId)\n\t\tresult.status = status\n\t\treturn result\n\t}\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { InMemoryEventLogger } from './chunk-MUYLRTSR.js';
2
- import { FlowRuntime } from './chunk-34LDT5EG.js';
1
+ import { InMemoryEventLogger } from './chunk-7EBKWATZ.js';
2
+ import { FlowRuntime } from './chunk-VDVUF25G.js';
3
3
 
4
4
  // src/testing/run-with-trace.ts
5
5
  async function runWithTrace(runtime, blueprint, initialState = {}, options = {}) {
@@ -21,5 +21,5 @@ async function runWithTrace(runtime, blueprint, initialState = {}, options = {})
21
21
  }
22
22
 
23
23
  export { runWithTrace };
24
- //# sourceMappingURL=chunk-NQORJ53O.js.map
25
- //# sourceMappingURL=chunk-NQORJ53O.js.map
24
+ //# sourceMappingURL=chunk-RF5EYEO6.js.map
25
+ //# sourceMappingURL=chunk-RF5EYEO6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing/run-with-trace.ts"],"names":[],"mappings":";;;;AA+BA,eAAsB,YAAA,CACrB,SACA,SAAA,EACA,YAAA,GAA2C,EAAC,EAC5C,OAAA,GAII,EAAC,EACJ;AACD,EAAA,MAAM,WAAA,GAAc,IAAI,mBAAA,EAAoB;AAC5C,EAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY;AAAA,IACnC,GAAG,OAAA,CAAQ,OAAA;AAAA,IACX,QAAA,EAAU;AAAA,GACV,CAAA;AAED,EAAA,IAAI;AACH,IAAA,MAAM,SAAS,MAAM,WAAA,CAAY,GAAA,CAAI,SAAA,EAAW,cAAc,OAAO,CAAA;AACrE,IAAA,IAAI,OAAA,CAAQ,IAAI,KAAA,EAAO;AACtB,MAAA,WAAA,CAAY,QAAA,CAAS,CAAA,kBAAA,EAAqB,SAAA,CAAU,EAAE,CAAA,CAAE,CAAA;AAAA,IACzD;AACA,IAAA,OAAO,MAAA;AAAA,EACR,SAAS,KAAA,EAAO;AACf,IAAA,WAAA,CAAY,QAAA,CAAS,CAAA,oBAAA,EAAuB,SAAA,CAAU,EAAE,CAAA,CAAE,CAAA;AAC1D,IAAA,MAAM,KAAA;AAAA,EACP;AACD","file":"chunk-NQORJ53O.js","sourcesContent":["import { FlowRuntime } from '../runtime'\nimport type { WorkflowBlueprint } from '../types'\nimport { InMemoryEventLogger } from './event-logger'\n\n/**\n * A test helper that executes a workflow and automatically prints a detailed\n * execution trace to the console if the workflow fails.\n *\n * @example\n * // In your test file (e.g., my-workflow.test.ts)\n * it('should process data correctly', async () => {\n * const flow = createFlow('my-flow')\n * .node('a', async () => ({ output: 1 }))\n * .node('b', async ({ input }) => ({ output: input + 1 })) // Bug: returns { output: 3 }\n * .edge('a', 'b')\n *\n * const runtime = new FlowRuntime({})\n *\n * // If this test fails, a full, human-readable trace of the execution\n * // (inputs, outputs, context changes) is printed to the console.\n * const result = await runWithTrace(runtime, flow.toBlueprint())\n *\n * expect(result.context.b).toBe(2)\n * })\n *\n * @param runtime The original FlowRuntime instance (its options will be used).\n * @param blueprint The WorkflowBlueprint to execute.\n * @param initialState The initial state for the workflow run.\n * @param options Additional options for the run.\n * @returns The WorkflowResult if successful.\n */\nexport async function runWithTrace<TContext extends Record<string, any>>(\n\truntime: FlowRuntime<TContext, any>,\n\tblueprint: WorkflowBlueprint,\n\tinitialState: Partial<TContext> | string = {},\n\toptions: {\n\t\tfunctionRegistry?: Map<string, any>\n\t\tstrict?: boolean\n\t\tsignal?: AbortSignal\n\t} = {},\n) {\n\tconst eventLogger = new InMemoryEventLogger()\n\tconst testRuntime = new FlowRuntime({\n\t\t...runtime.options,\n\t\teventBus: eventLogger,\n\t})\n\n\ttry {\n\t\tconst result = await testRuntime.run(blueprint, initialState, options)\n\t\tif (process.env.DEBUG) {\n\t\t\teventLogger.printLog(`Successful Trace: ${blueprint.id}`)\n\t\t}\n\t\treturn result\n\t} catch (error) {\n\t\teventLogger.printLog(`Failing Test Trace: ${blueprint.id}`)\n\t\tthrow error\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/testing/run-with-trace.ts"],"names":[],"mappings":";;;;AA+BA,eAAsB,YAAA,CACrB,SACA,SAAA,EACA,YAAA,GAA2C,EAAC,EAC5C,OAAA,GAII,EAAC,EACJ;AACD,EAAA,MAAM,WAAA,GAAc,IAAI,mBAAA,EAAoB;AAC5C,EAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY;AAAA,IACnC,GAAG,OAAA,CAAQ,OAAA;AAAA,IACX,QAAA,EAAU;AAAA,GACV,CAAA;AAED,EAAA,IAAI;AACH,IAAA,MAAM,SAAS,MAAM,WAAA,CAAY,GAAA,CAAI,SAAA,EAAW,cAAc,OAAO,CAAA;AACrE,IAAA,IAAI,OAAA,CAAQ,IAAI,KAAA,EAAO;AACtB,MAAA,WAAA,CAAY,QAAA,CAAS,CAAA,kBAAA,EAAqB,SAAA,CAAU,EAAE,CAAA,CAAE,CAAA;AAAA,IACzD;AACA,IAAA,OAAO,MAAA;AAAA,EACR,SAAS,KAAA,EAAO;AACf,IAAA,WAAA,CAAY,QAAA,CAAS,CAAA,oBAAA,EAAuB,SAAA,CAAU,EAAE,CAAA,CAAE,CAAA;AAC1D,IAAA,MAAM,KAAA;AAAA,EACP;AACD","file":"chunk-RF5EYEO6.js","sourcesContent":["import { FlowRuntime } from '../runtime'\nimport type { WorkflowBlueprint } from '../types'\nimport { InMemoryEventLogger } from './event-logger'\n\n/**\n * A test helper that executes a workflow and automatically prints a detailed\n * execution trace to the console if the workflow fails.\n *\n * @example\n * // In your test file (e.g., my-workflow.test.ts)\n * it('should process data correctly', async () => {\n * const flow = createFlow('my-flow')\n * .node('a', async () => ({ output: 1 }))\n * .node('b', async ({ input }) => ({ output: input + 1 })) // Bug: returns { output: 3 }\n * .edge('a', 'b')\n *\n * const runtime = new FlowRuntime({})\n *\n * // If this test fails, a full, human-readable trace of the execution\n * // (inputs, outputs, context changes) is printed to the console.\n * const result = await runWithTrace(runtime, flow.toBlueprint())\n *\n * expect(result.context.b).toBe(2)\n * })\n *\n * @param runtime The original FlowRuntime instance (its options will be used).\n * @param blueprint The WorkflowBlueprint to execute.\n * @param initialState The initial state for the workflow run.\n * @param options Additional options for the run.\n * @returns The WorkflowResult if successful.\n */\nexport async function runWithTrace<TContext extends Record<string, any>>(\n\truntime: FlowRuntime<TContext, any>,\n\tblueprint: WorkflowBlueprint,\n\tinitialState: Partial<TContext> | string = {},\n\toptions: {\n\t\tfunctionRegistry?: Map<string, any>\n\t\tstrict?: boolean\n\t\tsignal?: AbortSignal\n\t} = {},\n) {\n\tconst eventLogger = new InMemoryEventLogger()\n\tconst testRuntime = new FlowRuntime({\n\t\t...runtime.options,\n\t\teventBus: eventLogger,\n\t})\n\n\ttry {\n\t\tconst result = await testRuntime.run(blueprint, initialState, options)\n\t\tif (process.env.DEBUG) {\n\t\t\teventLogger.printLog(`Successful Trace: ${blueprint.id}`)\n\t\t}\n\t\treturn result\n\t} catch (error) {\n\t\teventLogger.printLog(`Failing Test Trace: ${blueprint.id}`)\n\t\tthrow error\n\t}\n}\n"]}
@@ -0,0 +1,39 @@
1
+ // src/sanitizer.ts
2
+ function sanitizeBlueprint(raw) {
3
+ let nodesArray = [];
4
+ if (Array.isArray(raw.nodes)) {
5
+ nodesArray = raw.nodes;
6
+ } else if (typeof raw.nodes === "object" && raw.nodes !== null) {
7
+ nodesArray = Object.values(raw.nodes);
8
+ }
9
+ const nodes = nodesArray.map((node) => ({
10
+ id: node.id,
11
+ uses: node.uses,
12
+ params: node.params,
13
+ inputs: node.inputs,
14
+ config: node.config
15
+ }));
16
+ let edgesArray = [];
17
+ if (Array.isArray(raw.edges)) {
18
+ edgesArray = raw.edges;
19
+ } else if (typeof raw.edges === "object" && raw.edges !== null) {
20
+ edgesArray = Object.values(raw.edges);
21
+ }
22
+ const edges = edgesArray.map((edge) => ({
23
+ source: edge.source,
24
+ target: edge.target,
25
+ action: edge.action,
26
+ condition: edge.condition,
27
+ transform: edge.transform
28
+ }));
29
+ return {
30
+ id: raw.id,
31
+ nodes,
32
+ edges,
33
+ metadata: raw.metadata
34
+ };
35
+ }
36
+
37
+ export { sanitizeBlueprint };
38
+ //# sourceMappingURL=chunk-TKSSRS5U.js.map
39
+ //# sourceMappingURL=chunk-TKSSRS5U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sanitizer.ts"],"names":[],"mappings":";AAOO,SAAS,kBAAkB,GAAA,EAA6B;AAC9D,EAAA,IAAI,aAAoB,EAAC;AACzB,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AAC7B,IAAA,UAAA,GAAa,GAAA,CAAI,KAAA;AAAA,EAClB,WAAW,OAAO,GAAA,CAAI,UAAU,QAAA,IAAY,GAAA,CAAI,UAAU,IAAA,EAAM;AAC/D,IAAA,UAAA,GAAa,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,EACrC;AAEA,EAAA,MAAM,KAAA,GAA0B,UAAA,CAAW,GAAA,CAAI,CAAC,IAAA,MAAe;AAAA,IAC9D,IAAI,IAAA,CAAK,EAAA;AAAA,IACT,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,IAAA,CAAK;AAAA,GACd,CAAE,CAAA;AAEF,EAAA,IAAI,aAAoB,EAAC;AACzB,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AAC7B,IAAA,UAAA,GAAa,GAAA,CAAI,KAAA;AAAA,EAClB,WAAW,OAAO,GAAA,CAAI,UAAU,QAAA,IAAY,GAAA,CAAI,UAAU,IAAA,EAAM;AAC/D,IAAA,UAAA,GAAa,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,EACrC;AAEA,EAAA,MAAM,KAAA,GAA0B,UAAA,CAAW,GAAA,CAAI,CAAC,IAAA,MAAe;AAAA,IAC9D,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,WAAW,IAAA,CAAK;AAAA,GACjB,CAAE,CAAA;AAEF,EAAA,OAAO;AAAA,IACN,IAAI,GAAA,CAAI,EAAA;AAAA,IACR,KAAA;AAAA,IACA,KAAA;AAAA,IACA,UAAU,GAAA,CAAI;AAAA,GACf;AACD","file":"chunk-TKSSRS5U.js","sourcesContent":["import type { EdgeDefinition, NodeDefinition, WorkflowBlueprint } from './types'\n\n/**\n * Sanitizes a raw workflow blueprint by removing extra properties\n * added by UI tools (e.g., position, style) and keeping only the\n * properties defined in NodeDefinition and EdgeDefinition.\n */\nexport function sanitizeBlueprint(raw: any): WorkflowBlueprint {\n\tlet nodesArray: any[] = []\n\tif (Array.isArray(raw.nodes)) {\n\t\tnodesArray = raw.nodes\n\t} else if (typeof raw.nodes === 'object' && raw.nodes !== null) {\n\t\tnodesArray = Object.values(raw.nodes)\n\t}\n\n\tconst nodes: NodeDefinition[] = nodesArray.map((node: any) => ({\n\t\tid: node.id,\n\t\tuses: node.uses,\n\t\tparams: node.params,\n\t\tinputs: node.inputs,\n\t\tconfig: node.config,\n\t}))\n\n\tlet edgesArray: any[] = []\n\tif (Array.isArray(raw.edges)) {\n\t\tedgesArray = raw.edges\n\t} else if (typeof raw.edges === 'object' && raw.edges !== null) {\n\t\tedgesArray = Object.values(raw.edges)\n\t}\n\n\tconst edges: EdgeDefinition[] = edgesArray.map((edge: any) => ({\n\t\tsource: edge.source,\n\t\ttarget: edge.target,\n\t\taction: edge.action,\n\t\tcondition: edge.condition,\n\t\ttransform: edge.transform,\n\t}))\n\n\treturn {\n\t\tid: raw.id,\n\t\tnodes,\n\t\tedges,\n\t\tmetadata: raw.metadata,\n\t}\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { executeBatch, processResults } from './chunk-SF5GQHUU.js';
2
- import { ExecutionContext } from './chunk-N4NLAIEN.js';
1
+ import { executeBatch, processResults } from './chunk-N63S5NEG.js';
2
+ import { ExecutionContext } from './chunk-LWN7HOD3.js';
3
3
  import { FlowcraftError } from './chunk-BCRWXTWX.js';
4
4
 
5
5
  // src/runtime/orchestrator.ts
@@ -63,12 +63,12 @@ var DefaultOrchestrator = class {
63
63
  }
64
64
  const isTraversalComplete = !traverser.hasMoreWork();
65
65
  const status = context.state.getStatus(isTraversalComplete);
66
- const result = await context.state.toResult(context.services.serializer);
66
+ const result = await context.state.toResult(context.services.serializer, context.executionId);
67
67
  result.status = status;
68
68
  return result;
69
69
  }
70
70
  };
71
71
 
72
72
  export { DefaultOrchestrator };
73
- //# sourceMappingURL=chunk-3YV6X6VQ.js.map
74
- //# sourceMappingURL=chunk-3YV6X6VQ.js.map
73
+ //# sourceMappingURL=chunk-TTOS7NW3.js.map
74
+ //# sourceMappingURL=chunk-TTOS7NW3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/orchestrator.ts"],"names":[],"mappings":";;;;;AAOO,IAAM,sBAAN,MAAmD;AAAA,EACzD,MAAM,GAAA,CAAI,OAAA,EAAqC,SAAA,EAAyD;AACvG,IAAA,MAAM,mBAAA,GAAsB,UAAA,CAAW,SAAA,EAAW,mBAAA,IAAuB,CAAA;AACzE,IAAA,MAAM,cAAA,GACL,OAAA,CAAQ,WAAA,IAAe,IAAA,IAAQ,OAAA,CAAQ,WAAA,GAAc,CAAA,GAAI,OAAA,CAAQ,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,EAAE,CAAA;AAEhH,IAAA,IAAI;AACH,MAAA,OAAA,CAAQ,QAAQ,cAAA,EAAe;AAAA,IAChC,SAAS,KAAA,EAAO;AACf,MAAA,IAAI,KAAA,YAAiB,YAAA,IAAgB,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AACjE,QAAA,MAAM,IAAI,cAAA,CAAe,oBAAA,EAAsB,EAAE,OAAA,EAAS,OAAO,CAAA;AAAA,MAClE;AACA,MAAA,MAAM,KAAA;AAAA,IACP;AAEA,IAAA,IAAI,UAAA,GAAa,CAAA;AACjB,IAAA,MAAM,aAAA,GAAgB,GAAA;AAEtB,IAAA,OAAO,SAAA,CAAU,aAAY,EAAG;AAC/B,MAAA,IAAI,EAAE,aAAa,aAAA,EAAe;AACjC,QAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,MAChF;AAEA,MAAA,IAAI;AACH,QAAA,OAAA,CAAQ,QAAQ,cAAA,EAAe;AAAA,MAChC,SAAS,KAAA,EAAO;AACf,QAAA,IAAI,KAAA,YAAiB,YAAA,IAAgB,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AACjE,UAAA,MAAM,IAAI,cAAA,CAAe,oBAAA,EAAsB,EAAE,OAAA,EAAS,OAAO,CAAA;AAAA,QAClE;AACA,QAAA,MAAM,KAAA;AAAA,MACP;AAEA,MAAA,MAAM,UAAA,GAAa,UAAU,aAAA,EAAc;AAC3C,MAAA,MAAM,gBAAA,GAAmB,UAAU,mBAAA,EAAoB;AACvD,MAAA,MAAM,iBAAiB,IAAI,gBAAA;AAAA,QAC1B,gBAAA;AAAA,QACA,OAAA,CAAQ,KAAA;AAAA,QACR,OAAA,CAAQ,YAAA;AAAA,QACR,OAAA,CAAQ,WAAA;AAAA,QACR,OAAA,CAAQ,OAAA;AAAA,QACR,OAAA,CAAQ,QAAA;AAAA,QACR,OAAA,CAAQ,MAAA;AAAA,QACR,OAAA,CAAQ;AAAA,OACT;AACA,MAAA,MAAM,iBAAiB,MAAM,YAAA;AAAA,QAC5B,UAAA;AAAA,QACA,gBAAA;AAAA,QACA,OAAA,CAAQ,KAAA;AAAA,QACR,CAAC,MAAA,KAAmB,OAAA,CAAQ,OAAA,CAAQ,kBAAA,CAAmB,QAAQ,cAAc,CAAA;AAAA,QAC7E,OAAA,CAAQ,OAAA;AAAA,QACR;AAAA,OACD;AAEA,MAAA,MAAM,cAAA;AAAA,QACL,cAAA;AAAA,QACA,SAAA;AAAA,QACA,OAAA,CAAQ,KAAA;AAAA,QACR,OAAA,CAAQ,OAAA;AAAA,QACR,OAAA,CAAQ,SAAA;AAAA,QACR,OAAA,CAAQ;AAAA,OACT;AAEA,MAAA,IAAI,OAAA,CAAQ,KAAA,CAAM,UAAA,EAAW,EAAG;AAC/B,QAAA;AAAA,MACD;AAAA,IACD;AAEA,IAAA,MAAM,mBAAA,GAAsB,CAAC,SAAA,CAAU,WAAA,EAAY;AACnD,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,SAAA,CAAU,mBAAmB,CAAA;AAC1D,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,KAAA,CAAM,SAAS,OAAA,CAAQ,QAAA,CAAS,UAAA,EAAY,OAAA,CAAQ,WAAW,CAAA;AAC5F,IAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,IAAA,OAAO,MAAA;AAAA,EACR;AACD","file":"chunk-TTOS7NW3.js","sourcesContent":["import { FlowcraftError } from '../errors'\nimport type { WorkflowResult } from '../types'\nimport { ExecutionContext } from './execution-context'\nimport { executeBatch, processResults } from './orchestrators/utils'\nimport type { GraphTraverser } from './traverser'\nimport type { IOrchestrator } from './types'\n\nexport class DefaultOrchestrator implements IOrchestrator {\n\tasync run(context: ExecutionContext<any, any>, traverser: GraphTraverser): Promise<WorkflowResult<any>> {\n\t\tconst hardwareConcurrency = globalThis.navigator?.hardwareConcurrency || 4\n\t\tconst maxConcurrency =\n\t\t\tcontext.concurrency != null && context.concurrency > 0 ? context.concurrency : Math.min(hardwareConcurrency, 10)\n\n\t\ttry {\n\t\t\tcontext.signal?.throwIfAborted()\n\t\t} catch (error) {\n\t\t\tif (error instanceof DOMException && error.name === 'AbortError') {\n\t\t\t\tthrow new FlowcraftError('Workflow cancelled', { isFatal: false })\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\n\t\tlet iterations = 0\n\t\tconst maxIterations = 10000\n\n\t\twhile (traverser.hasMoreWork()) {\n\t\t\tif (++iterations > maxIterations) {\n\t\t\t\tthrow new Error('Traversal exceeded maximum iterations, possible infinite loop')\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcontext.signal?.throwIfAborted()\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DOMException && error.name === 'AbortError') {\n\t\t\t\t\tthrow new FlowcraftError('Workflow cancelled', { isFatal: false })\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\tconst readyNodes = traverser.getReadyNodes()\n\t\t\tconst dynamicBlueprint = traverser.getDynamicBlueprint()\n\t\t\tconst updatedContext = new ExecutionContext(\n\t\t\t\tdynamicBlueprint,\n\t\t\t\tcontext.state,\n\t\t\t\tcontext.nodeRegistry,\n\t\t\t\tcontext.executionId,\n\t\t\t\tcontext.runtime,\n\t\t\t\tcontext.services,\n\t\t\t\tcontext.signal,\n\t\t\t\tcontext.concurrency,\n\t\t\t)\n\t\t\tconst settledResults = await executeBatch(\n\t\t\t\treadyNodes,\n\t\t\t\tdynamicBlueprint,\n\t\t\t\tcontext.state,\n\t\t\t\t(nodeId: string) => context.runtime.getExecutorForNode(nodeId, updatedContext),\n\t\t\t\tcontext.runtime,\n\t\t\t\tmaxConcurrency,\n\t\t\t)\n\n\t\t\tawait processResults(\n\t\t\t\tsettledResults,\n\t\t\t\ttraverser,\n\t\t\t\tcontext.state,\n\t\t\t\tcontext.runtime,\n\t\t\t\tcontext.blueprint,\n\t\t\t\tcontext.executionId,\n\t\t\t)\n\n\t\t\tif (context.state.isAwaiting()) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst isTraversalComplete = !traverser.hasMoreWork()\n\t\tconst status = context.state.getStatus(isTraversalComplete)\n\t\tconst result = await context.state.toResult(context.services.serializer, context.executionId)\n\t\tresult.status = status\n\t\treturn result\n\t}\n}\n"]}
@@ -0,0 +1,103 @@
1
+ // src/runtime/orchestrators/replay.ts
2
+ var ReplayOrchestrator = class {
3
+ /**
4
+ * Creates a new ReplayOrchestrator with a sequence of recorded workflow events.
5
+ *
6
+ * @param events - Array of FlowcraftEvent objects representing the recorded workflow execution
7
+ */
8
+ constructor(events) {
9
+ this.events = events;
10
+ }
11
+ /**
12
+ * Replays the recorded workflow events to reconstruct the workflow state.
13
+ *
14
+ * This method filters events for the specific execution, applies each event in sequence
15
+ * to rebuild the context state, and returns the final reconstructed workflow result.
16
+ * Replayed executions always have a "completed" status since they reconstruct the final state.
17
+ *
18
+ * @param context - The execution context containing state and services
19
+ * @param _traverser - Graph traverser (unused in replay mode)
20
+ * @returns Promise resolving to the reconstructed workflow result
21
+ */
22
+ async run(context, _traverser) {
23
+ const executionEvents = this.events.filter((event) => {
24
+ if ("executionId" in event.payload) {
25
+ return event.payload.executionId === context.executionId;
26
+ }
27
+ return false;
28
+ });
29
+ const fallbackMap = /* @__PURE__ */ new Map();
30
+ for (const event of executionEvents) {
31
+ await this.applyEvent(event, context, fallbackMap);
32
+ }
33
+ const includeExecutionId = executionEvents.length > 0;
34
+ const result = await context.state.toResult(
35
+ context.services.serializer,
36
+ includeExecutionId ? context.executionId : void 0
37
+ );
38
+ result.status = "completed";
39
+ return result;
40
+ }
41
+ /**
42
+ * Applies a single workflow event to reconstruct the execution state.
43
+ *
44
+ * This method handles different event types by updating the workflow state accordingly,
45
+ * including node completions, context changes, errors, fallbacks, and workflow control events.
46
+ *
47
+ * @param event - The workflow event to apply
48
+ * @param context - The execution context to update
49
+ * @param fallbackMap - Map tracking fallback node relationships (fallbackNodeId -> originalNodeId)
50
+ */
51
+ async applyEvent(event, context, fallbackMap) {
52
+ const { type, payload } = event;
53
+ switch (type) {
54
+ case "node:start":
55
+ break;
56
+ case "node:finish": {
57
+ const originalNodeId = fallbackMap.get(payload.nodeId);
58
+ if (originalNodeId) {
59
+ await context.state.addCompletedNode(originalNodeId, payload.result.output);
60
+ } else {
61
+ await context.state.addCompletedNode(payload.nodeId, payload.result.output);
62
+ }
63
+ break;
64
+ }
65
+ case "context:change":
66
+ if (payload.op === "set") {
67
+ await context.state.getContext().set(payload.key, payload.value);
68
+ } else if (payload.op === "delete") {
69
+ await context.state.getContext().delete(payload.key);
70
+ }
71
+ break;
72
+ case "node:error":
73
+ context.state.addError(payload.nodeId, payload.error);
74
+ break;
75
+ case "node:fallback":
76
+ fallbackMap.set(payload.fallback, payload.nodeId);
77
+ context.state.markFallbackExecuted();
78
+ break;
79
+ case "node:retry":
80
+ break;
81
+ case "edge:evaluate":
82
+ break;
83
+ case "workflow:stall":
84
+ case "workflow:pause":
85
+ if ("remainingNodes" in payload) {
86
+ for (let i = 0; i < payload.remainingNodes; i++) {
87
+ await context.state.markAsAwaiting(`node-${i}`);
88
+ }
89
+ }
90
+ break;
91
+ case "batch:start":
92
+ break;
93
+ case "batch:finish":
94
+ for (const _result of payload.results) {
95
+ }
96
+ break;
97
+ }
98
+ }
99
+ };
100
+
101
+ export { ReplayOrchestrator };
102
+ //# sourceMappingURL=chunk-UNORA7EM.js.map
103
+ //# sourceMappingURL=chunk-UNORA7EM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/orchestrators/replay.ts"],"names":[],"mappings":"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","file":"chunk-UNORA7EM.js","sourcesContent":["import type { FlowcraftEvent, WorkflowResult } from '../../types'\nimport type { ExecutionContext } from '../execution-context'\nimport type { GraphTraverser } from '../traverser'\nimport type { IOrchestrator } from '../types'\n\n/**\n * An orchestrator that replays a pre-recorded sequence of workflow events\n * to reconstruct the workflow state without executing any node logic.\n *\n * This enables time-travel debugging by allowing developers to inspect\n * the exact state of a workflow at any point in its execution history.\n */\nexport class ReplayOrchestrator implements IOrchestrator {\n\t/**\n\t * Creates a new ReplayOrchestrator with a sequence of recorded workflow events.\n\t *\n\t * @param events - Array of FlowcraftEvent objects representing the recorded workflow execution\n\t */\n\tconstructor(private events: FlowcraftEvent[]) {}\n\n\t/**\n\t * Replays the recorded workflow events to reconstruct the workflow state.\n\t *\n\t * This method filters events for the specific execution, applies each event in sequence\n\t * to rebuild the context state, and returns the final reconstructed workflow result.\n\t * Replayed executions always have a \"completed\" status since they reconstruct the final state.\n\t *\n\t * @param context - The execution context containing state and services\n\t * @param _traverser - Graph traverser (unused in replay mode)\n\t * @returns Promise resolving to the reconstructed workflow result\n\t */\n\tasync run(context: ExecutionContext<any, any>, _traverser: GraphTraverser): Promise<WorkflowResult<any>> {\n\t\tconst executionEvents = this.events.filter((event) => {\n\t\t\tif ('executionId' in event.payload) {\n\t\t\t\treturn event.payload.executionId === context.executionId\n\t\t\t}\n\t\t\treturn false\n\t\t})\n\n\t\tconst fallbackMap = new Map<string, string>()\n\n\t\tfor (const event of executionEvents) {\n\t\t\tawait this.applyEvent(event, context, fallbackMap)\n\t\t}\n\n\t\tconst includeExecutionId = executionEvents.length > 0\n\t\tconst result = await context.state.toResult(\n\t\t\tcontext.services.serializer,\n\t\t\tincludeExecutionId ? context.executionId : undefined,\n\t\t)\n\t\tresult.status = 'completed'\n\t\treturn result\n\t}\n\n\t/**\n\t * Applies a single workflow event to reconstruct the execution state.\n\t *\n\t * This method handles different event types by updating the workflow state accordingly,\n\t * including node completions, context changes, errors, fallbacks, and workflow control events.\n\t *\n\t * @param event - The workflow event to apply\n\t * @param context - The execution context to update\n\t * @param fallbackMap - Map tracking fallback node relationships (fallbackNodeId -> originalNodeId)\n\t */\n\tprivate async applyEvent(\n\t\tevent: FlowcraftEvent,\n\t\tcontext: ExecutionContext<any, any>,\n\t\tfallbackMap: Map<string, string>,\n\t): Promise<void> {\n\t\tconst { type, payload } = event\n\n\t\tswitch (type) {\n\t\t\tcase 'node:start':\n\t\t\t\tbreak\n\n\t\t\tcase 'node:finish': {\n\t\t\t\tconst originalNodeId = fallbackMap.get(payload.nodeId)\n\t\t\t\tif (originalNodeId) {\n\t\t\t\t\tawait context.state.addCompletedNode(originalNodeId, payload.result.output)\n\t\t\t\t} else {\n\t\t\t\t\tawait context.state.addCompletedNode(payload.nodeId, payload.result.output)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcase 'context:change':\n\t\t\t\tif (payload.op === 'set') {\n\t\t\t\t\tawait context.state.getContext().set(payload.key, payload.value)\n\t\t\t\t} else if (payload.op === 'delete') {\n\t\t\t\t\tawait context.state.getContext().delete(payload.key)\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tcase 'node:error':\n\t\t\t\tcontext.state.addError(payload.nodeId, payload.error)\n\t\t\t\tbreak\n\n\t\t\tcase 'node:fallback':\n\t\t\t\tfallbackMap.set(payload.fallback, payload.nodeId)\n\t\t\t\tcontext.state.markFallbackExecuted()\n\t\t\t\tbreak\n\n\t\t\tcase 'node:retry':\n\t\t\t\tbreak\n\n\t\t\tcase 'edge:evaluate':\n\t\t\t\tbreak\n\n\t\t\tcase 'workflow:stall':\n\t\t\tcase 'workflow:pause':\n\t\t\t\tif ('remainingNodes' in payload) {\n\t\t\t\t\tfor (let i = 0; i < payload.remainingNodes; i++) {\n\t\t\t\t\t\tawait context.state.markAsAwaiting(`node-${i}`)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tcase 'batch:start':\n\t\t\t\tbreak\n\n\t\t\tcase 'batch:finish':\n\t\t\t\tfor (const _result of payload.results) {\n\t\t\t\t\t// TODO?\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\tbreak\n\t\t}\n\t}\n}\n"]}
@@ -1,20 +1,20 @@
1
- import { WorkflowLogicHandler } from './chunk-VB7VNXR7.js';
1
+ import { WorkflowLogicHandler } from './chunk-HXSK5P2X.js';
2
2
  import { NodeExecutorFactory } from './chunk-DL7KVYZF.js';
3
3
  import { WorkflowScheduler } from './chunk-LM4ACVHL.js';
4
- import { BatchGatherNode } from './chunk-BC4G7OM6.js';
5
- import { BatchScatterNode } from './chunk-RM677CNU.js';
6
4
  import { SleepNode } from './chunk-HNHM3FDK.js';
7
- import { SubflowNode } from './chunk-BTCZU2DJ.js';
8
- import { GraphTraverser } from './chunk-H4JTZYIT.js';
5
+ import { SubflowNode } from './chunk-4TVWI6Y6.js';
9
6
  import { WaitNode } from './chunk-IDTYHLDQ.js';
10
7
  import { WebhookNode } from './chunk-I53JB2KW.js';
11
- import { sanitizeBlueprint } from './chunk-HLN72CCU.js';
8
+ import { GraphTraverser } from './chunk-H4JTZYIT.js';
9
+ import { BatchGatherNode } from './chunk-BC4G7OM6.js';
10
+ import { BatchScatterNode } from './chunk-RM677CNU.js';
11
+ import { sanitizeBlueprint } from './chunk-TKSSRS5U.js';
12
12
  import { analyzeBlueprint } from './chunk-ZLW4QOTS.js';
13
- import { DefaultOrchestrator } from './chunk-3YV6X6VQ.js';
14
- import { ExecutionContext } from './chunk-N4NLAIEN.js';
15
- import { WorkflowState } from './chunk-5BOUGXZO.js';
13
+ import { DefaultOrchestrator } from './chunk-TTOS7NW3.js';
14
+ import { ExecutionContext } from './chunk-LWN7HOD3.js';
15
+ import { WorkflowState } from './chunk-VSKDQVCG.js';
16
16
  import { NullLogger } from './chunk-4PELJWF7.js';
17
- import { JsonSerializer } from './chunk-6X5BERRF.js';
17
+ import { JsonSerializer } from './chunk-6RKHCJUU.js';
18
18
  import { DIContainer, ServiceTokens } from './chunk-WWGFIYKW.js';
19
19
  import { FlowcraftError } from './chunk-BCRWXTWX.js';
20
20
  import { PropertyEvaluator } from './chunk-PH2IYZHV.js';
@@ -361,14 +361,14 @@ var FlowRuntime = class {
361
361
  const nextSteps = await this.determineNextNodes(blueprint, awaitingNodeId, resumeData, contextImpl, executionId);
362
362
  if (nextSteps.length === 0) {
363
363
  workflowState.clearAwaiting(awaitingNodeId);
364
- const result = await workflowState.toResult(this.serializer);
364
+ const result = await workflowState.toResult(this.serializer, executionId);
365
365
  result.status = "completed";
366
366
  return result;
367
367
  }
368
368
  const traverserForResume = new GraphTraverser(blueprint);
369
369
  const allPredecessors = traverserForResume.getAllPredecessors();
370
370
  for (const { node, edge } of nextSteps) {
371
- await this.applyEdgeTransform(edge, resumeData, node, contextImpl, allPredecessors);
371
+ await this.applyEdgeTransform(edge, resumeData, node, contextImpl, allPredecessors, executionId);
372
372
  }
373
373
  const traverser = GraphTraverser.fromState(blueprint, workflowState);
374
374
  const nextNodeDefs = nextSteps.map((s) => s.node);
@@ -468,14 +468,63 @@ var FlowRuntime = class {
468
468
  async determineNextNodes(blueprint, nodeId, result, context, executionId) {
469
469
  return this.logicHandler.determineNextNodes(blueprint, nodeId, result, context, executionId);
470
470
  }
471
- async applyEdgeTransform(edge, sourceResult, targetNode, context, allPredecessors) {
472
- return this.logicHandler.applyEdgeTransform(edge, sourceResult, targetNode, context, allPredecessors);
471
+ async applyEdgeTransform(edge, sourceResult, targetNode, context, allPredecessors, executionId) {
472
+ return this.logicHandler.applyEdgeTransform(edge, sourceResult, targetNode, context, allPredecessors, executionId);
473
473
  }
474
474
  async resolveNodeInput(nodeId, blueprint, context) {
475
475
  return this.logicHandler.resolveNodeInput(nodeId, blueprint, context);
476
476
  }
477
+ /**
478
+ * Replay a workflow execution from a pre-recorded event history.
479
+ * This reconstructs the final workflow state without executing any node logic,
480
+ * enabling time-travel debugging and post-mortem analysis.
481
+ *
482
+ * @param blueprint The workflow blueprint
483
+ * @param events The recorded event history for the execution
484
+ * @param executionId Optional execution ID to filter events (if events contain multiple executions)
485
+ * @returns The reconstructed workflow result
486
+ */
487
+ async replay(blueprint, events, executionId) {
488
+ let filteredEvents = events;
489
+ if (executionId) {
490
+ filteredEvents = events.filter((event) => {
491
+ if ("executionId" in event.payload) {
492
+ return event.payload.executionId === executionId;
493
+ }
494
+ return false;
495
+ });
496
+ }
497
+ if (!executionId) {
498
+ const workflowStartEvent = filteredEvents.find((e) => e.type === "workflow:start");
499
+ if (workflowStartEvent && "executionId" in workflowStartEvent.payload) {
500
+ executionId = workflowStartEvent.payload.executionId;
501
+ } else {
502
+ throw new FlowcraftError("Cannot determine execution ID from events", { isFatal: true });
503
+ }
504
+ }
505
+ const tempContext = this._setupExecutionContext(
506
+ blueprint,
507
+ {},
508
+ { strict: false }
509
+ // allow cycles in replay
510
+ );
511
+ const executionContext = new ExecutionContext(
512
+ blueprint,
513
+ tempContext.state,
514
+ tempContext.nodeRegistry,
515
+ executionId,
516
+ this,
517
+ tempContext.services,
518
+ tempContext.signal,
519
+ tempContext.concurrency
520
+ );
521
+ const { ReplayOrchestrator } = await import('./runtime/orchestrators/replay.js');
522
+ const replayOrchestrator = new ReplayOrchestrator(filteredEvents);
523
+ const traverser = new GraphTraverser(blueprint);
524
+ return await replayOrchestrator.run(executionContext, traverser);
525
+ }
477
526
  };
478
527
 
479
528
  export { FlowRuntime };
480
- //# sourceMappingURL=chunk-34LDT5EG.js.map
481
- //# sourceMappingURL=chunk-34LDT5EG.js.map
529
+ //# sourceMappingURL=chunk-VDVUF25G.js.map
530
+ //# sourceMappingURL=chunk-VDVUF25G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/runtime.ts"],"names":[],"mappings":"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","file":"chunk-VDVUF25G.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 { WebhookNode } from '../nodes/webhook'\nimport { sanitizeBlueprint } from '../sanitizer'\nimport { JsonSerializer } from '../serializer'\nimport type {\n\tContextImplementation,\n\tEdgeDefinition,\n\tFlowcraftEvent,\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\twebhook: WebhookNode,\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(checkIntervalMs?: number): void {\n\t\tif (checkIntervalMs !== undefined) {\n\t\t\tthis.scheduler = new WorkflowScheduler(this, checkIntervalMs)\n\t\t}\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, executionId)\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, executionId)\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\texecutionId?: string,\n\t): Promise<void> {\n\t\treturn this.logicHandler.applyEdgeTransform(edge, sourceResult, targetNode, context, allPredecessors, executionId)\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\t/**\n\t * Replay a workflow execution from a pre-recorded event history.\n\t * This reconstructs the final workflow state without executing any node logic,\n\t * enabling time-travel debugging and post-mortem analysis.\n\t *\n\t * @param blueprint The workflow blueprint\n\t * @param events The recorded event history for the execution\n\t * @param executionId Optional execution ID to filter events (if events contain multiple executions)\n\t * @returns The reconstructed workflow result\n\t */\n\tasync replay(\n\t\tblueprint: WorkflowBlueprint,\n\t\tevents: FlowcraftEvent[],\n\t\texecutionId?: string,\n\t): Promise<WorkflowResult<TContext>> {\n\t\tlet filteredEvents = events\n\t\tif (executionId) {\n\t\t\tfilteredEvents = events.filter((event) => {\n\t\t\t\tif ('executionId' in event.payload) {\n\t\t\t\t\treturn event.payload.executionId === executionId\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t})\n\t\t}\n\n\t\tif (!executionId) {\n\t\t\tconst workflowStartEvent = filteredEvents.find((e) => e.type === 'workflow:start')\n\t\t\tif (workflowStartEvent && 'executionId' in workflowStartEvent.payload) {\n\t\t\t\texecutionId = workflowStartEvent.payload.executionId\n\t\t\t} else {\n\t\t\t\tthrow new FlowcraftError('Cannot determine execution ID from events', { isFatal: true })\n\t\t\t}\n\t\t}\n\n\t\tconst tempContext = this._setupExecutionContext(\n\t\t\tblueprint,\n\t\t\t{},\n\t\t\t{ strict: false }, // allow cycles in replay\n\t\t)\n\n\t\tconst executionContext = new ExecutionContext(\n\t\t\tblueprint,\n\t\t\ttempContext.state,\n\t\t\ttempContext.nodeRegistry,\n\t\t\texecutionId,\n\t\t\tthis,\n\t\t\ttempContext.services,\n\t\t\ttempContext.signal,\n\t\t\ttempContext.concurrency,\n\t\t)\n\n\t\tconst { ReplayOrchestrator } = await import('./orchestrators/replay')\n\t\tconst replayOrchestrator = new ReplayOrchestrator(filteredEvents)\n\n\t\tconst traverser = new GraphTraverser(blueprint)\n\n\t\treturn await replayOrchestrator.run(executionContext, traverser)\n\t}\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { TrackedAsyncContext, AsyncContextView, Context } from './chunk-XDI4TJHA.js';
1
+ import { TrackedAsyncContext, AsyncContextView, Context } from './chunk-ZETQCNEF.js';
2
2
  import { FlowcraftError } from './chunk-BCRWXTWX.js';
3
3
 
4
4
  // src/runtime/state.ts
@@ -31,6 +31,15 @@ var WorkflowState = class {
31
31
  }
32
32
  }
33
33
  }
34
+ /**
35
+ * Configure the context to emit events when modified.
36
+ * This is called after the ExecutionContext is created.
37
+ */
38
+ setEventEmitter(eventBus, executionId, sourceNode) {
39
+ if (this.context instanceof TrackedAsyncContext) {
40
+ this.context.configureEventEmitter(eventBus, executionId, sourceNode);
41
+ }
42
+ }
34
43
  async addCompletedNode(nodeId, output) {
35
44
  this._completedNodes.add(nodeId);
36
45
  await this.context.set(`_outputs.${nodeId}`, output);
@@ -108,12 +117,15 @@ var WorkflowState = class {
108
117
  if (isTraversalComplete) return "completed";
109
118
  return "stalled";
110
119
  }
111
- async toResult(serializer) {
120
+ async toResult(serializer, executionId) {
112
121
  const contextJSON = await this.context.toJSON();
113
122
  if (!this._isAwaiting && contextJSON._awaitingNodeIds) {
114
123
  delete contextJSON._awaitingNodeIds;
115
124
  delete contextJSON._awaitingDetails;
116
125
  }
126
+ if (executionId) {
127
+ contextJSON._executionId = executionId;
128
+ }
117
129
  return {
118
130
  context: contextJSON,
119
131
  serializedContext: serializer.serialize(contextJSON),
@@ -124,5 +136,5 @@ var WorkflowState = class {
124
136
  };
125
137
 
126
138
  export { WorkflowState };
127
- //# sourceMappingURL=chunk-5BOUGXZO.js.map
128
- //# sourceMappingURL=chunk-5BOUGXZO.js.map
139
+ //# sourceMappingURL=chunk-VSKDQVCG.js.map
140
+ //# sourceMappingURL=chunk-VSKDQVCG.js.map