flowcraft 2.6.1 → 2.7.1

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-2TSADFQX.js +46 -0
  9. package/dist/chunk-2TSADFQX.js.map +1 -0
  10. package/dist/chunk-3Y5O5EGB.js +3 -0
  11. package/dist/{chunk-NVJ3ZO3P.js.map → chunk-3Y5O5EGB.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-BTCZU2DJ.js → chunk-7EMUOH77.js} +4 -4
  17. package/dist/{chunk-BTCZU2DJ.js.map → chunk-7EMUOH77.js.map} +1 -1
  18. package/dist/{chunk-QSQ2BSGG.js → chunk-7M6FHFHP.js} +4 -4
  19. package/dist/{chunk-QSQ2BSGG.js.map → chunk-7M6FHFHP.js.map} +1 -1
  20. package/dist/{chunk-IWTFVGMK.js → chunk-AKDL2ZX7.js} +2 -2
  21. package/dist/{chunk-IWTFVGMK.js.map → chunk-AKDL2ZX7.js.map} +1 -1
  22. package/dist/{chunk-2YLGY3R2.js → chunk-BCMR7Y4U.js} +7 -7
  23. package/dist/chunk-BCMR7Y4U.js.map +1 -0
  24. package/dist/{chunk-34LDT5EG.js → chunk-BEHVGFIM.js} +85 -34
  25. package/dist/chunk-BEHVGFIM.js.map +1 -0
  26. package/dist/{chunk-3YV6X6VQ.js → chunk-DV2CXHOY.js} +5 -5
  27. package/dist/chunk-DV2CXHOY.js.map +1 -0
  28. package/dist/chunk-HFJXYY4E.js +3 -0
  29. package/dist/chunk-HFJXYY4E.js.map +1 -0
  30. package/dist/{chunk-VB7VNXR7.js → chunk-HXSK5P2X.js} +11 -5
  31. package/dist/chunk-HXSK5P2X.js.map +1 -0
  32. package/dist/{chunk-N4NLAIEN.js → chunk-L3MX5MTA.js} +4 -3
  33. package/dist/chunk-L3MX5MTA.js.map +1 -0
  34. package/dist/{chunk-5BOUGXZO.js → chunk-L46TQXCV.js} +22 -6
  35. package/dist/chunk-L46TQXCV.js.map +1 -0
  36. package/dist/{chunk-SF5GQHUU.js → chunk-N63S5NEG.js} +10 -3
  37. package/dist/chunk-N63S5NEG.js.map +1 -0
  38. package/dist/{chunk-C3ZT7FNO.js → chunk-RAZWRNAJ.js} +5 -5
  39. package/dist/chunk-RAZWRNAJ.js.map +1 -0
  40. package/dist/chunk-TKSSRS5U.js +39 -0
  41. package/dist/chunk-TKSSRS5U.js.map +1 -0
  42. package/dist/{chunk-O3QJFRXS.js → chunk-U7DKCIWT.js} +37 -19
  43. package/dist/chunk-U7DKCIWT.js.map +1 -0
  44. package/dist/chunk-UNORA7EM.js +103 -0
  45. package/dist/chunk-UNORA7EM.js.map +1 -0
  46. package/dist/{chunk-NQORJ53O.js → chunk-XZZWIJ4G.js} +4 -4
  47. package/dist/{chunk-NQORJ53O.js.map → chunk-XZZWIJ4G.js.map} +1 -1
  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 +18 -15
  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 +12 -12
  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 +14 -13
  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 +11 -11
  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 +20 -17
  104. package/dist/testing/run-with-trace.d.ts +1 -1
  105. package/dist/testing/run-with-trace.js +16 -15
  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-CKhffqyb.d.ts} +49 -6
  109. package/dist/types.d.ts +1 -1
  110. package/package.json +2 -2
  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
@@ -0,0 +1,4 @@
1
+ export { IEventStore, InMemoryEventStore, PersistentEventBusAdapter } from './persistent-event-bus.js';
2
+ import '../types-CKhffqyb.js';
3
+ import '../errors.js';
4
+ import '../container.js';
@@ -0,0 +1,4 @@
1
+ import '../chunk-3Y5O5EGB.js';
2
+ export { InMemoryEventStore, PersistentEventBusAdapter } from '../chunk-2TSADFQX.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,69 @@
1
+ import { z as FlowcraftEvent, A as IEventBus } from '../types-CKhffqyb.js';
2
+ import '../errors.js';
3
+ import '../container.js';
4
+
5
+ /**
6
+ * Interface for a persistent storage mechanism for events.
7
+ * Implementations can store events in databases, log streams, files, etc.
8
+ */
9
+ interface IEventStore {
10
+ /**
11
+ * Store an event persistently.
12
+ * @param event The event to store
13
+ * @param executionId The execution ID for grouping events
14
+ */
15
+ store(event: FlowcraftEvent, executionId: string): Promise<void>;
16
+ /**
17
+ * Retrieve all events for a specific execution.
18
+ * @param executionId The execution ID
19
+ * @returns Array of events in chronological order
20
+ */
21
+ retrieve(executionId: string): Promise<FlowcraftEvent[]>;
22
+ /**
23
+ * Retrieve events for multiple executions.
24
+ * @param executionIds Array of execution IDs
25
+ * @returns Map of execution ID to array of events
26
+ */
27
+ retrieveMultiple(executionIds: string[]): Promise<Map<string, FlowcraftEvent[]>>;
28
+ }
29
+ /**
30
+ * A pluggable event bus adapter that persists all workflow events
31
+ * to a configurable storage backend, enabling time-travel debugging and replay.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // Using a database-backed store
36
+ * const eventStore = new DatabaseEventStore(dbConnection)
37
+ * const eventBus = new PersistentEventBusAdapter(eventStore)
38
+ * const runtime = new FlowRuntime({ eventBus })
39
+ *
40
+ * // Later, replay the execution
41
+ * const events = await eventStore.retrieve(executionId)
42
+ * const finalState = await runtime.replay(blueprint, events)
43
+ * ```
44
+ */
45
+ declare class PersistentEventBusAdapter implements IEventBus {
46
+ private store;
47
+ constructor(store: IEventStore);
48
+ /**
49
+ * Emit an event by storing it persistently.
50
+ * Also emits to console for debugging (can be made configurable).
51
+ */
52
+ emit(event: FlowcraftEvent): Promise<void>;
53
+ }
54
+ /**
55
+ * Simple in-memory event store for testing and development.
56
+ * Not suitable for production use.
57
+ */
58
+ declare class InMemoryEventStore implements IEventStore {
59
+ private events;
60
+ store(event: FlowcraftEvent, executionId: string): Promise<void>;
61
+ retrieve(executionId: string): Promise<FlowcraftEvent[]>;
62
+ retrieveMultiple(executionIds: string[]): Promise<Map<string, FlowcraftEvent[]>>;
63
+ /**
64
+ * Clear all stored events (useful for testing).
65
+ */
66
+ clear(): void;
67
+ }
68
+
69
+ export { type IEventStore, InMemoryEventStore, PersistentEventBusAdapter };
@@ -0,0 +1,3 @@
1
+ export { InMemoryEventStore, PersistentEventBusAdapter } from '../chunk-2TSADFQX.js';
2
+ //# sourceMappingURL=persistent-event-bus.js.map
3
+ //# sourceMappingURL=persistent-event-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"persistent-event-bus.js"}
@@ -1,4 +1,4 @@
1
- import { h as WorkflowBlueprint, z as FlowcraftEvent } from './types-Cv5JcMwI.js';
1
+ import { h as WorkflowBlueprint, z as FlowcraftEvent } from './types-CKhffqyb.js';
2
2
  import './errors.js';
3
3
  import './container.js';
4
4
 
@@ -0,0 +1,46 @@
1
+ // src/adapters/persistent-event-bus.ts
2
+ var PersistentEventBusAdapter = class {
3
+ constructor(store) {
4
+ this.store = store;
5
+ }
6
+ /**
7
+ * Emit an event by storing it persistently.
8
+ * Also emits to console for debugging (can be made configurable).
9
+ */
10
+ async emit(event) {
11
+ let executionId = "unknown";
12
+ if ("executionId" in event.payload) {
13
+ executionId = event.payload.executionId;
14
+ }
15
+ await this.store.store(event, executionId);
16
+ }
17
+ };
18
+ var InMemoryEventStore = class {
19
+ events = /* @__PURE__ */ new Map();
20
+ async store(event, executionId) {
21
+ if (!this.events.has(executionId)) {
22
+ this.events.set(executionId, []);
23
+ }
24
+ this.events.get(executionId)?.push(event);
25
+ }
26
+ async retrieve(executionId) {
27
+ return this.events.get(executionId) || [];
28
+ }
29
+ async retrieveMultiple(executionIds) {
30
+ const result = /* @__PURE__ */ new Map();
31
+ for (const id of executionIds) {
32
+ result.set(id, await this.retrieve(id));
33
+ }
34
+ return result;
35
+ }
36
+ /**
37
+ * Clear all stored events (useful for testing).
38
+ */
39
+ clear() {
40
+ this.events.clear();
41
+ }
42
+ };
43
+
44
+ export { InMemoryEventStore, PersistentEventBusAdapter };
45
+ //# sourceMappingURL=chunk-2TSADFQX.js.map
46
+ //# sourceMappingURL=chunk-2TSADFQX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/persistent-event-bus.ts"],"names":[],"mappings":";AA6CO,IAAM,4BAAN,MAAqD;AAAA,EAC3D,YAAoB,KAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMzC,MAAM,KAAK,KAAA,EAAsC;AAChD,IAAA,IAAI,WAAA,GAAc,SAAA;AAClB,IAAA,IAAI,aAAA,IAAiB,MAAM,OAAA,EAAS;AACnC,MAAA,WAAA,GAAc,MAAM,OAAA,CAAQ,WAAA;AAAA,IAC7B;AACA,IAAA,MAAM,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,KAAA,EAAO,WAAW,CAAA;AAAA,EAC1C;AACD;AAMO,IAAM,qBAAN,MAAgD;AAAA,EAC9C,MAAA,uBAAa,GAAA,EAA8B;AAAA,EAEnD,MAAM,KAAA,CAAM,KAAA,EAAuB,WAAA,EAAoC;AACtE,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,WAAW,CAAA,EAAG;AAClC,MAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,WAAA,EAAa,EAAE,CAAA;AAAA,IAChC;AACA,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,WAAW,CAAA,EAAG,KAAK,KAAK,CAAA;AAAA,EACzC;AAAA,EAEA,MAAM,SAAS,WAAA,EAAgD;AAC9D,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,WAAW,KAAK,EAAC;AAAA,EACzC;AAAA,EAEA,MAAM,iBAAiB,YAAA,EAAgE;AACtF,IAAA,MAAM,MAAA,uBAAa,GAAA,EAA8B;AACjD,IAAA,KAAA,MAAW,MAAM,YAAA,EAAc;AAC9B,MAAA,MAAA,CAAO,IAAI,EAAA,EAAI,MAAM,IAAA,CAAK,QAAA,CAAS,EAAE,CAAC,CAAA;AAAA,IACvC;AACA,IAAA,OAAO,MAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACb,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAAA,EACnB;AACD","file":"chunk-2TSADFQX.js","sourcesContent":["import type { FlowcraftEvent, IEventBus } from '../types'\n\n/**\n * Interface for a persistent storage mechanism for events.\n * Implementations can store events in databases, log streams, files, etc.\n */\nexport interface IEventStore {\n\t/**\n\t * Store an event persistently.\n\t * @param event The event to store\n\t * @param executionId The execution ID for grouping events\n\t */\n\tstore(event: FlowcraftEvent, executionId: string): Promise<void>\n\n\t/**\n\t * Retrieve all events for a specific execution.\n\t * @param executionId The execution ID\n\t * @returns Array of events in chronological order\n\t */\n\tretrieve(executionId: string): Promise<FlowcraftEvent[]>\n\n\t/**\n\t * Retrieve events for multiple executions.\n\t * @param executionIds Array of execution IDs\n\t * @returns Map of execution ID to array of events\n\t */\n\tretrieveMultiple(executionIds: string[]): Promise<Map<string, FlowcraftEvent[]>>\n}\n\n/**\n * A pluggable event bus adapter that persists all workflow events\n * to a configurable storage backend, enabling time-travel debugging and replay.\n *\n * @example\n * ```typescript\n * // Using a database-backed store\n * const eventStore = new DatabaseEventStore(dbConnection)\n * const eventBus = new PersistentEventBusAdapter(eventStore)\n * const runtime = new FlowRuntime({ eventBus })\n *\n * // Later, replay the execution\n * const events = await eventStore.retrieve(executionId)\n * const finalState = await runtime.replay(blueprint, events)\n * ```\n */\nexport class PersistentEventBusAdapter implements IEventBus {\n\tconstructor(private store: IEventStore) {}\n\n\t/**\n\t * Emit an event by storing it persistently.\n\t * Also emits to console for debugging (can be made configurable).\n\t */\n\tasync emit(event: FlowcraftEvent): Promise<void> {\n\t\tlet executionId = 'unknown'\n\t\tif ('executionId' in event.payload) {\n\t\t\texecutionId = event.payload.executionId as string\n\t\t}\n\t\tawait this.store.store(event, executionId)\n\t}\n}\n\n/**\n * Simple in-memory event store for testing and development.\n * Not suitable for production use.\n */\nexport class InMemoryEventStore implements IEventStore {\n\tprivate events = new Map<string, FlowcraftEvent[]>()\n\n\tasync store(event: FlowcraftEvent, executionId: string): Promise<void> {\n\t\tif (!this.events.has(executionId)) {\n\t\t\tthis.events.set(executionId, [])\n\t\t}\n\t\tthis.events.get(executionId)?.push(event)\n\t}\n\n\tasync retrieve(executionId: string): Promise<FlowcraftEvent[]> {\n\t\treturn this.events.get(executionId) || []\n\t}\n\n\tasync retrieveMultiple(executionIds: string[]): Promise<Map<string, FlowcraftEvent[]>> {\n\t\tconst result = new Map<string, FlowcraftEvent[]>()\n\t\tfor (const id of executionIds) {\n\t\t\tresult.set(id, await this.retrieve(id))\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Clear all stored events (useful for testing).\n\t */\n\tclear(): void {\n\t\tthis.events.clear()\n\t}\n}\n"]}
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=chunk-3Y5O5EGB.js.map
3
+ //# sourceMappingURL=chunk-3Y5O5EGB.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-NVJ3ZO3P.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-3Y5O5EGB.js"}
@@ -25,5 +25,5 @@ var JsonSerializer = class {
25
25
  };
26
26
 
27
27
  export { JsonSerializer };
28
- //# sourceMappingURL=chunk-6X5BERRF.js.map
29
- //# sourceMappingURL=chunk-6X5BERRF.js.map
28
+ //# sourceMappingURL=chunk-6RKHCJUU.js.map
29
+ //# sourceMappingURL=chunk-6RKHCJUU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/serializer.ts"],"names":[],"mappings":";AASO,IAAM,iBAAN,MAA4C;AAAA,EAC1C,SAAA,GAAY,KAAA;AAAA,EAEpB,UAAU,IAAA,EAAmC;AAC5C,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,EAAG;AACxC,MAAA,IAAI,KAAA,YAAiB,GAAA,IAAO,KAAA,YAAiB,GAAA,IAAO,iBAAiB,IAAA,EAAM;AAC1E,QAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACpB,UAAA,OAAA,CAAQ,IAAA;AAAA,YACP;AAAA,WACD;AACA,UAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,QAClB;AAAA,MACD;AAAA,IACD;AACA,IAAA,IAAI;AACH,MAAA,OAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,IAC3B,CAAA,CAAA,MAAQ;AAEP,MAAA,OAAA,CAAQ,KAAK,wFAAwF,CAAA;AACrG,MAAA,OAAO,KAAK,SAAA,CAAU,EAAE,oBAAoB,IAAA,EAAM,OAAA,EAAS,wCAAwC,CAAA;AAAA,IACpG;AAAA,EACD;AAAA,EAEA,YAAY,IAAA,EAAmC;AAC9C,IAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACvB;AACD","file":"chunk-6X5BERRF.js","sourcesContent":["import type { ISerializer } from './types'\n\n/**\n * A default serializer using standard JSON.\n *\n * @warning This implementation is lossy and does not handle complex data types\n * like `Date`, `Map`, `Set`, `undefined`, etc. It is recommended to provide a robust\n * serializer like `superjson` if working with complex data types.\n */\nexport class JsonSerializer implements ISerializer {\n\tprivate hasWarned = false\n\n\tserialize(data: Record<string, any>): string {\n\t\tfor (const value of Object.values(data)) {\n\t\t\tif (value instanceof Map || value instanceof Set || value instanceof Date) {\n\t\t\t\tif (!this.hasWarned) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t'[Flowcraft] Warning: Default JsonSerializer does not support Map, Set, or Date types. Data may be lost. Consider providing a custom ISerializer (e.g., using superjson).',\n\t\t\t\t\t)\n\t\t\t\t\tthis.hasWarned = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\treturn JSON.stringify(data)\n\t\t} catch {\n\t\t\t// Handle circular references by returning a safe representation\n\t\t\tconsole.warn('[Flowcraft] Warning: Circular reference detected in context. Using safe serialization.')\n\t\t\treturn JSON.stringify({ _circularReference: true, message: 'Context contains circular references' })\n\t\t}\n\t}\n\n\tdeserialize(text: string): Record<string, any> {\n\t\treturn JSON.parse(text)\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/serializer.ts"],"names":[],"mappings":";AASO,IAAM,iBAAN,MAA4C;AAAA,EAC1C,SAAA,GAAY,KAAA;AAAA,EAEpB,UAAU,IAAA,EAAmC;AAC5C,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,EAAG;AACxC,MAAA,IAAI,KAAA,YAAiB,GAAA,IAAO,KAAA,YAAiB,GAAA,IAAO,iBAAiB,IAAA,EAAM;AAC1E,QAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACpB,UAAA,OAAA,CAAQ,IAAA;AAAA,YACP;AAAA,WACD;AACA,UAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,QAClB;AAAA,MACD;AAAA,IACD;AACA,IAAA,IAAI;AACH,MAAA,OAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,IAC3B,CAAA,CAAA,MAAQ;AACP,MAAA,OAAA,CAAQ,KAAK,wFAAwF,CAAA;AACrG,MAAA,OAAO,KAAK,SAAA,CAAU,EAAE,oBAAoB,IAAA,EAAM,OAAA,EAAS,wCAAwC,CAAA;AAAA,IACpG;AAAA,EACD;AAAA,EAEA,YAAY,IAAA,EAAmC;AAC9C,IAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACvB;AACD","file":"chunk-6RKHCJUU.js","sourcesContent":["import type { ISerializer } from './types'\n\n/**\n * A default serializer using standard JSON.\n *\n * @warning This implementation is lossy and does not handle complex data types\n * like `Date`, `Map`, `Set`, `undefined`, etc. It is recommended to provide a robust\n * serializer like `superjson` if working with complex data types.\n */\nexport class JsonSerializer implements ISerializer {\n\tprivate hasWarned = false\n\n\tserialize(data: Record<string, any>): string {\n\t\tfor (const value of Object.values(data)) {\n\t\t\tif (value instanceof Map || value instanceof Set || value instanceof Date) {\n\t\t\t\tif (!this.hasWarned) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t'[Flowcraft] Warning: Default JsonSerializer does not support Map, Set, or Date types. Data may be lost. Consider providing a custom ISerializer (e.g., using superjson).',\n\t\t\t\t\t)\n\t\t\t\t\tthis.hasWarned = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\treturn JSON.stringify(data)\n\t\t} catch {\n\t\t\tconsole.warn('[Flowcraft] Warning: Circular reference detected in context. Using safe serialization.')\n\t\t\treturn JSON.stringify({ _circularReference: true, message: 'Context contains circular references' })\n\t\t}\n\t}\n\n\tdeserialize(text: string): Record<string, any> {\n\t\treturn JSON.parse(text)\n\t}\n}\n"]}
@@ -57,9 +57,13 @@ var InMemoryEventLogger = class {
57
57
  console.log(` - Condition: ${payload.condition || "N/A"} | Result: ${payload.result}`);
58
58
  break;
59
59
  case "context:change":
60
- console.log(
61
- ` - Node "${payload.sourceNode}" wrote to context -> Key: "${payload.key}" | Value: ${JSON.stringify(payload.value)}`
62
- );
60
+ if (payload.op === "set") {
61
+ console.log(
62
+ ` - Node "${payload.sourceNode}" wrote to context -> Key: "${payload.key}" | Value: ${JSON.stringify(payload.value)}`
63
+ );
64
+ } else if (payload.op === "delete") {
65
+ console.log(` - Node "${payload.sourceNode}" deleted from context -> Key: "${payload.key}"`);
66
+ }
63
67
  break;
64
68
  case "node:finish":
65
69
  console.log(` - Node: "${payload.nodeId}" | Result: ${JSON.stringify(payload.result)}`);
@@ -78,5 +82,5 @@ var InMemoryEventLogger = class {
78
82
  };
79
83
 
80
84
  export { InMemoryEventLogger };
81
- //# sourceMappingURL=chunk-MUYLRTSR.js.map
82
- //# sourceMappingURL=chunk-MUYLRTSR.js.map
85
+ //# sourceMappingURL=chunk-7EBKWATZ.js.map
86
+ //# sourceMappingURL=chunk-7EBKWATZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/event-logger.ts"],"names":[],"mappings":"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","file":"chunk-7EBKWATZ.js","sourcesContent":["import type { FlowcraftEvent, IEventBus } from '../types'\n\n/**\n * A test utility that implements IEventBus to capture all workflow events\n * in memory, acting as a \"flight recorder\" for behavioral testing.\n *\n * @example\n * // In your test file (e.g., resiliency.test.ts)\n * it('should retry a node on failure', async () => {\n * const eventLogger = new InMemoryEventLogger();\n * const runtime = new FlowRuntime({ eventBus: eventLogger });\n *\n * const flow = createFlow('retry-flow')\n * .node('api-call', vi.fn().mockRejectedValueOnce(new Error('fail')), {\n * config: { maxRetries: 2 },\n * });\n *\n * await runtime.run(flow.toBlueprint());\n *\n * // Assert against the captured event history to prove behavior.\n * const retryEvents = eventLogger.filter('node:retry');\n * expect(retryEvents).toHaveLength(1); // The first attempt is not a \"retry\"\n * });\n */\nexport class InMemoryEventLogger implements IEventBus {\n\tpublic readonly events: FlowcraftEvent[] = []\n\n\t/**\n\t * Clears all captured events.\n\t */\n\tpublic clear(): void {\n\t\tthis.events.length = 0\n\t}\n\n\t/**\n\t * The `emit` method required by the IEventBus interface.\n\t * It simply pushes the received event into the internal events array.\n\t * @param event The FlowcraftEvent to record.\n\t */\n\tpublic async emit(event: FlowcraftEvent): Promise<void> {\n\t\tthis.events.push(event)\n\t}\n\n\t/**\n\t * Finds the first event of a specific type.\n\t * @param type The event type to find (e.g., 'node:error').\n\t * @returns The first matching event, or undefined if not found.\n\t */\n\tpublic find<T extends FlowcraftEvent['type']>(type: T): Extract<FlowcraftEvent, { type: T }> | undefined {\n\t\treturn this.events.find((e) => e.type === type) as Extract<FlowcraftEvent, { type: T }> | undefined\n\t}\n\n\t/**\n\t * Filters events to find all occurrences of a specific type.\n\t * @param type The event type to filter by.\n\t * @returns An array of matching events.\n\t */\n\tpublic filter<T extends FlowcraftEvent['type']>(type: T): Extract<FlowcraftEvent, { type: T }>[] {\n\t\treturn this.events.filter((e) => e.type === type) as Extract<FlowcraftEvent, { type: T }>[]\n\t}\n\n\t/**\n\t * Prints a formatted log of all captured events to the console.\n\t * Ideal for debugging failing tests.\n\t * @param title A title for the log output.\n\t */\n\tpublic printLog(title = 'Workflow Execution Trace'): void {\n\t\tconsole.log(`\\n--- ${title} ---`)\n\t\tif (this.events.length === 0) {\n\t\t\tconsole.log('No events were captured.')\n\t\t\tconsole.log('----------------------------------\\n')\n\t\t\treturn\n\t\t}\n\n\t\tthis.events.forEach((event, index) => {\n\t\t\tconst { type, payload } = event\n\t\t\tconsole.log(`\\n[${index + 1}] ${type}`)\n\n\t\t\t// Custom formatting for a more intuitive trace\n\t\t\tswitch (type) {\n\t\t\t\tcase 'node:start':\n\t\t\t\t\tconsole.log(` - Node: \"${payload.nodeId}\" | Input: ${JSON.stringify(payload.input)}`)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'edge:evaluate':\n\t\t\t\t\tconsole.log(` - Edge: \"${payload.source}\" -> \"${payload.target}\"`)\n\t\t\t\t\tconsole.log(` - Condition: ${payload.condition || 'N/A'} | Result: ${payload.result}`)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'context:change':\n\t\t\t\t\tif (payload.op === 'set') {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t` - Node \"${payload.sourceNode}\" wrote to context -> Key: \"${payload.key}\" | Value: ${JSON.stringify(payload.value)}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t} else if (payload.op === 'delete') {\n\t\t\t\t\t\tconsole.log(` - Node \"${payload.sourceNode}\" deleted from context -> Key: \"${payload.key}\"`)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\tcase 'node:finish':\n\t\t\t\t\tconsole.log(` - Node: \"${payload.nodeId}\" | Result: ${JSON.stringify(payload.result)}`)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'node:error':\n\t\t\t\t\tconsole.log(` - Node: \"${payload.nodeId}\"`)\n\t\t\t\t\tconsole.error(' - Error:', payload.error)\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tconsole.log(` - Payload: ${JSON.stringify(payload, null, 2)}`)\n\t\t\t}\n\t\t})\n\t\tconsole.log(`\\n--- End of Trace ---`)\n\t}\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { GraphTraverser } from './chunk-H4JTZYIT.js';
2
2
  import { analyzeBlueprint } from './chunk-ZLW4QOTS.js';
3
- import { ExecutionContext } from './chunk-N4NLAIEN.js';
4
- import { WorkflowState } from './chunk-5BOUGXZO.js';
3
+ import { ExecutionContext } from './chunk-L3MX5MTA.js';
4
+ import { WorkflowState } from './chunk-L46TQXCV.js';
5
5
  import { FlowcraftError } from './chunk-BCRWXTWX.js';
6
6
  import { BaseNode } from './chunk-LNK7LZER.js';
7
7
 
@@ -86,5 +86,5 @@ var SubflowNode = class extends BaseNode {
86
86
  };
87
87
 
88
88
  export { SubflowNode };
89
- //# sourceMappingURL=chunk-BTCZU2DJ.js.map
90
- //# sourceMappingURL=chunk-BTCZU2DJ.js.map
89
+ //# sourceMappingURL=chunk-7EMUOH77.js.map
90
+ //# sourceMappingURL=chunk-7EMUOH77.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/nodes/subflow.ts"],"names":["subAnalysis"],"mappings":"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","file":"chunk-BTCZU2DJ.js","sourcesContent":["import { analyzeBlueprint } from '../analysis'\nimport { FlowcraftError } from '../errors'\nimport { BaseNode } from '../node'\nimport { ExecutionContext } from '../runtime/execution-context'\nimport { WorkflowState } from '../runtime/state'\nimport { GraphTraverser } from '../runtime/traverser'\nimport type { NodeContext, NodeResult } from '../types'\n\nexport class SubflowNode 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\tconst { blueprintId, inputs, outputs } = this.params ?? {}\n\t\tconst { runtime, workflowState } = context.dependencies\n\n\t\tif (!blueprintId) {\n\t\t\tthrow new FlowcraftError(`Subflow node '${this.nodeId}' is missing 'blueprintId' parameter.`, { isFatal: true })\n\t\t}\n\n\t\tconst subBlueprint =\n\t\t\t(runtime as any).blueprints?.[blueprintId] || (runtime as any).runtime?.blueprints?.[blueprintId]\n\t\tif (!subBlueprint) {\n\t\t\tthrow new FlowcraftError(`Sub-blueprint '${blueprintId}' not found in runtime registry.`, { isFatal: true })\n\t\t}\n\n\t\tconst subflowInitialContext: Record<string, any> = {}\n\n\t\tif (inputs) {\n\t\t\t// explicit inputs\n\t\t\tfor (const [targetKey, sourceKey] of Object.entries(inputs as Record<string, string>)) {\n\t\t\t\tlet value = await context.context.get(sourceKey as any)\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tvalue = await context.context.get(`_outputs.${sourceKey}` as any)\n\t\t\t\t}\n\t\t\t\tsubflowInitialContext[targetKey] = value\n\t\t\t}\n\t\t} else if (context.input !== undefined) {\n\t\t\t// pass the parent node's input to the subflow's start nodes\n\t\t\tconst subAnalysis = analyzeBlueprint(subBlueprint)\n\t\t\tfor (const startNodeId of subAnalysis.startNodeIds) {\n\t\t\t\tconst inputKey = `_inputs.${startNodeId}`\n\t\t\t\tsubflowInitialContext[inputKey] = context.input\n\t\t\t}\n\t\t}\n\n\t\tconst subflowState = new WorkflowState(subflowInitialContext)\n\t\tconst subflowExecContext = new ExecutionContext(\n\t\t\tsubBlueprint,\n\t\t\tsubflowState,\n\t\t\truntime.nodeRegistry,\n\t\t\truntime.executionId,\n\t\t\truntime.runtime,\n\t\t\truntime.services,\n\t\t\truntime.signal,\n\t\t\truntime.concurrency,\n\t\t)\n\t\tconst subflowTraverser = new GraphTraverser(subBlueprint)\n\n\t\tconst subflowResult = await runtime.runtime.orchestrator.run(subflowExecContext, subflowTraverser)\n\n\t\tif (subflowResult.status === 'awaiting') {\n\t\t\tawait workflowState.markAsAwaiting(this.nodeId ?? '')\n\t\t\tconst subflowStateKey = `_subflowState.${this.nodeId}`\n\t\t\tawait context.context.set(subflowStateKey as any, subflowResult.serializedContext)\n\t\t\treturn { output: undefined }\n\t\t}\n\n\t\tif (subflowResult.status !== 'completed') {\n\t\t\tconst firstError = subflowResult.errors?.[0]\n\t\t\tconst errorMessage = firstError?.message || 'Unknown error'\n\t\t\tthrow new FlowcraftError(\n\t\t\t\t`Sub-workflow '${blueprintId}' did not complete successfully. Status: ${subflowResult.status}. Error: ${errorMessage}`,\n\t\t\t\t{\n\t\t\t\t\tcause: firstError,\n\t\t\t\t\tnodeId: this.nodeId,\n\t\t\t\t\tblueprintId,\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\tconst subflowFinalContext = subflowResult.context as Record<string, any>\n\n\t\tif (outputs) {\n\t\t\tfor (const [parentKey, subKey] of Object.entries(outputs as Record<string, string>)) {\n\t\t\t\tconst value = subflowFinalContext[`_outputs.${subKey}`] ?? subflowFinalContext[subKey]\n\t\t\t\tawait context.context.set(parentKey as any, value)\n\t\t\t}\n\t\t\treturn { output: subflowFinalContext }\n\t\t}\n\n\t\tconst subAnalysis = analyzeBlueprint(subBlueprint)\n\t\tif (subAnalysis.terminalNodeIds.length === 1) {\n\t\t\tconst terminalId = subAnalysis.terminalNodeIds[0]\n\t\t\treturn { output: subflowFinalContext[`_outputs.${terminalId}`] }\n\t\t}\n\n\t\tconst terminalOutputs: Record<string, any> = {}\n\t\tfor (const terminalId of subAnalysis.terminalNodeIds) {\n\t\t\tterminalOutputs[terminalId] = subflowFinalContext[`_outputs.${terminalId}`]\n\t\t}\n\t\treturn { output: terminalOutputs }\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/nodes/subflow.ts"],"names":["subAnalysis"],"mappings":"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","file":"chunk-7EMUOH77.js","sourcesContent":["import { analyzeBlueprint } from '../analysis'\nimport { FlowcraftError } from '../errors'\nimport { BaseNode } from '../node'\nimport { ExecutionContext } from '../runtime/execution-context'\nimport { WorkflowState } from '../runtime/state'\nimport { GraphTraverser } from '../runtime/traverser'\nimport type { NodeContext, NodeResult } from '../types'\n\nexport class SubflowNode 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\tconst { blueprintId, inputs, outputs } = this.params ?? {}\n\t\tconst { runtime, workflowState } = context.dependencies\n\n\t\tif (!blueprintId) {\n\t\t\tthrow new FlowcraftError(`Subflow node '${this.nodeId}' is missing 'blueprintId' parameter.`, { isFatal: true })\n\t\t}\n\n\t\tconst subBlueprint =\n\t\t\t(runtime as any).blueprints?.[blueprintId] || (runtime as any).runtime?.blueprints?.[blueprintId]\n\t\tif (!subBlueprint) {\n\t\t\tthrow new FlowcraftError(`Sub-blueprint '${blueprintId}' not found in runtime registry.`, { isFatal: true })\n\t\t}\n\n\t\tconst subflowInitialContext: Record<string, any> = {}\n\n\t\tif (inputs) {\n\t\t\t// explicit inputs\n\t\t\tfor (const [targetKey, sourceKey] of Object.entries(inputs as Record<string, string>)) {\n\t\t\t\tlet value = await context.context.get(sourceKey as any)\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tvalue = await context.context.get(`_outputs.${sourceKey}` as any)\n\t\t\t\t}\n\t\t\t\tsubflowInitialContext[targetKey] = value\n\t\t\t}\n\t\t} else if (context.input !== undefined) {\n\t\t\t// pass the parent node's input to the subflow's start nodes\n\t\t\tconst subAnalysis = analyzeBlueprint(subBlueprint)\n\t\t\tfor (const startNodeId of subAnalysis.startNodeIds) {\n\t\t\t\tconst inputKey = `_inputs.${startNodeId}`\n\t\t\t\tsubflowInitialContext[inputKey] = context.input\n\t\t\t}\n\t\t}\n\n\t\tconst subflowState = new WorkflowState(subflowInitialContext)\n\t\tconst subflowExecContext = new ExecutionContext(\n\t\t\tsubBlueprint,\n\t\t\tsubflowState,\n\t\t\truntime.nodeRegistry,\n\t\t\truntime.executionId,\n\t\t\truntime.runtime,\n\t\t\truntime.services,\n\t\t\truntime.signal,\n\t\t\truntime.concurrency,\n\t\t)\n\t\tconst subflowTraverser = new GraphTraverser(subBlueprint)\n\n\t\tconst subflowResult = await runtime.runtime.orchestrator.run(subflowExecContext, subflowTraverser)\n\n\t\tif (subflowResult.status === 'awaiting') {\n\t\t\tawait workflowState.markAsAwaiting(this.nodeId ?? '')\n\t\t\tconst subflowStateKey = `_subflowState.${this.nodeId}`\n\t\t\tawait context.context.set(subflowStateKey as any, subflowResult.serializedContext)\n\t\t\treturn { output: undefined }\n\t\t}\n\n\t\tif (subflowResult.status !== 'completed') {\n\t\t\tconst firstError = subflowResult.errors?.[0]\n\t\t\tconst errorMessage = firstError?.message || 'Unknown error'\n\t\t\tthrow new FlowcraftError(\n\t\t\t\t`Sub-workflow '${blueprintId}' did not complete successfully. Status: ${subflowResult.status}. Error: ${errorMessage}`,\n\t\t\t\t{\n\t\t\t\t\tcause: firstError,\n\t\t\t\t\tnodeId: this.nodeId,\n\t\t\t\t\tblueprintId,\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\tconst subflowFinalContext = subflowResult.context as Record<string, any>\n\n\t\tif (outputs) {\n\t\t\tfor (const [parentKey, subKey] of Object.entries(outputs as Record<string, string>)) {\n\t\t\t\tconst value = subflowFinalContext[`_outputs.${subKey}`] ?? subflowFinalContext[subKey]\n\t\t\t\tawait context.context.set(parentKey as any, value)\n\t\t\t}\n\t\t\treturn { output: subflowFinalContext }\n\t\t}\n\n\t\tconst subAnalysis = analyzeBlueprint(subBlueprint)\n\t\tif (subAnalysis.terminalNodeIds.length === 1) {\n\t\t\tconst terminalId = subAnalysis.terminalNodeIds[0]\n\t\t\treturn { output: subflowFinalContext[`_outputs.${terminalId}`] }\n\t\t}\n\n\t\tconst terminalOutputs: Record<string, any> = {}\n\t\tfor (const terminalId of subAnalysis.terminalNodeIds) {\n\t\t\tterminalOutputs[terminalId] = subflowFinalContext[`_outputs.${terminalId}`]\n\t\t}\n\t\treturn { output: terminalOutputs }\n\t}\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { DefaultOrchestrator } from './chunk-3YV6X6VQ.js';
1
+ import { DefaultOrchestrator } from './chunk-DV2CXHOY.js';
2
2
  import { NullLogger } from './chunk-4PELJWF7.js';
3
- import { JsonSerializer } from './chunk-6X5BERRF.js';
3
+ import { JsonSerializer } from './chunk-6RKHCJUU.js';
4
4
  import { DIContainer, ServiceTokens } from './chunk-WWGFIYKW.js';
5
5
  import { PropertyEvaluator } from './chunk-PH2IYZHV.js';
6
6
 
@@ -21,5 +21,5 @@ function createDefaultContainer(options = {}) {
21
21
  }
22
22
 
23
23
  export { createDefaultContainer };
24
- //# sourceMappingURL=chunk-QSQ2BSGG.js.map
25
- //# sourceMappingURL=chunk-QSQ2BSGG.js.map
24
+ //# sourceMappingURL=chunk-7M6FHFHP.js.map
25
+ //# sourceMappingURL=chunk-7M6FHFHP.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/container-factory.ts"],"names":[],"mappings":";;;;;;;AA4BO,SAAS,sBAAA,CACf,OAAA,GAA2C,EAAC,EAC9B;AACd,EAAA,MAAM,SAAA,GAAY,IAAI,WAAA,EAAY;AAElC,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,MAAA,EAAQ,QAAQ,MAAA,IAAU,IAAI,YAAY,CAAA;AAC3E,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,UAAA,EAAY,QAAQ,UAAA,IAAc,IAAI,gBAAgB,CAAA;AACvF,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,SAAA,EAAW,QAAQ,SAAA,IAAa,IAAI,mBAAmB,CAAA;AACxF,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,QAAA,EAAU,QAAQ,QAAA,IAAY,EAAE,MAAM,YAAY;AAAA,EAAC,GAAG,CAAA;AACvF,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,UAAA,EAAY,OAAA,CAAQ,UAAA,IAAc,EAAE,CAAA;AACrE,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,YAAA,EAAc,OAAA,CAAQ,QAAA,IAAY,EAAE,CAAA;AACrE,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,iBAAA,EAAmB,OAAA,CAAQ,UAAA,IAAc,EAAE,CAAA;AAC5E,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,YAAA,EAAc,OAAA,CAAQ,YAAA,IAAiB,EAAoB,CAAA;AAE5F,EAAA,SAAA,CAAU,gBAAgB,aAAA,CAAc,YAAA,EAAc,MAAM,IAAI,qBAAqB,CAAA;AAErF,EAAA,OAAO,SAAA;AACR","file":"chunk-QSQ2BSGG.js","sourcesContent":["import { DIContainer, ServiceTokens } from './container'\nimport { PropertyEvaluator } from './evaluator'\nimport { NullLogger } from './logger'\nimport { DefaultOrchestrator } from './runtime/orchestrator'\nimport { JsonSerializer } from './serializer'\nimport type {\n\tIEvaluator,\n\tIEventBus,\n\tILogger,\n\tISerializer,\n\tMiddleware,\n\tNodeClass,\n\tNodeFunction,\n\tRuntimeDependencies,\n\tWorkflowBlueprint,\n} from './types'\n\nexport interface ContainerOptions<TDependencies extends RuntimeDependencies = RuntimeDependencies> {\n\tlogger?: ILogger\n\tserializer?: ISerializer\n\tevaluator?: IEvaluator\n\teventBus?: IEventBus\n\tmiddleware?: Middleware[]\n\tregistry?: Record<string, NodeFunction | NodeClass>\n\tblueprints?: Record<string, WorkflowBlueprint>\n\tdependencies?: TDependencies\n}\n\nexport function createDefaultContainer<TDependencies extends RuntimeDependencies = RuntimeDependencies>(\n\toptions: ContainerOptions<TDependencies> = {},\n): DIContainer {\n\tconst container = new DIContainer()\n\n\tcontainer.register(ServiceTokens.Logger, options.logger || new NullLogger())\n\tcontainer.register(ServiceTokens.Serializer, options.serializer || new JsonSerializer())\n\tcontainer.register(ServiceTokens.Evaluator, options.evaluator || new PropertyEvaluator())\n\tcontainer.register(ServiceTokens.EventBus, options.eventBus || { emit: async () => {} })\n\tcontainer.register(ServiceTokens.Middleware, options.middleware || [])\n\tcontainer.register(ServiceTokens.NodeRegistry, options.registry || {})\n\tcontainer.register(ServiceTokens.BlueprintRegistry, options.blueprints || {})\n\tcontainer.register(ServiceTokens.Dependencies, options.dependencies || ({} as TDependencies))\n\n\tcontainer.registerFactory(ServiceTokens.Orchestrator, () => new DefaultOrchestrator())\n\n\treturn container\n}\n"]}
1
+ {"version":3,"sources":["../src/container-factory.ts"],"names":[],"mappings":";;;;;;;AA4BO,SAAS,sBAAA,CACf,OAAA,GAA2C,EAAC,EAC9B;AACd,EAAA,MAAM,SAAA,GAAY,IAAI,WAAA,EAAY;AAElC,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,MAAA,EAAQ,QAAQ,MAAA,IAAU,IAAI,YAAY,CAAA;AAC3E,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,UAAA,EAAY,QAAQ,UAAA,IAAc,IAAI,gBAAgB,CAAA;AACvF,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,SAAA,EAAW,QAAQ,SAAA,IAAa,IAAI,mBAAmB,CAAA;AACxF,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,QAAA,EAAU,QAAQ,QAAA,IAAY,EAAE,MAAM,YAAY;AAAA,EAAC,GAAG,CAAA;AACvF,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,UAAA,EAAY,OAAA,CAAQ,UAAA,IAAc,EAAE,CAAA;AACrE,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,YAAA,EAAc,OAAA,CAAQ,QAAA,IAAY,EAAE,CAAA;AACrE,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,iBAAA,EAAmB,OAAA,CAAQ,UAAA,IAAc,EAAE,CAAA;AAC5E,EAAA,SAAA,CAAU,SAAS,aAAA,CAAc,YAAA,EAAc,OAAA,CAAQ,YAAA,IAAiB,EAAoB,CAAA;AAE5F,EAAA,SAAA,CAAU,gBAAgB,aAAA,CAAc,YAAA,EAAc,MAAM,IAAI,qBAAqB,CAAA;AAErF,EAAA,OAAO,SAAA;AACR","file":"chunk-7M6FHFHP.js","sourcesContent":["import { DIContainer, ServiceTokens } from './container'\nimport { PropertyEvaluator } from './evaluator'\nimport { NullLogger } from './logger'\nimport { DefaultOrchestrator } from './runtime/orchestrator'\nimport { JsonSerializer } from './serializer'\nimport type {\n\tIEvaluator,\n\tIEventBus,\n\tILogger,\n\tISerializer,\n\tMiddleware,\n\tNodeClass,\n\tNodeFunction,\n\tRuntimeDependencies,\n\tWorkflowBlueprint,\n} from './types'\n\nexport interface ContainerOptions<TDependencies extends RuntimeDependencies = RuntimeDependencies> {\n\tlogger?: ILogger\n\tserializer?: ISerializer\n\tevaluator?: IEvaluator\n\teventBus?: IEventBus\n\tmiddleware?: Middleware[]\n\tregistry?: Record<string, NodeFunction | NodeClass>\n\tblueprints?: Record<string, WorkflowBlueprint>\n\tdependencies?: TDependencies\n}\n\nexport function createDefaultContainer<TDependencies extends RuntimeDependencies = RuntimeDependencies>(\n\toptions: ContainerOptions<TDependencies> = {},\n): DIContainer {\n\tconst container = new DIContainer()\n\n\tcontainer.register(ServiceTokens.Logger, options.logger || new NullLogger())\n\tcontainer.register(ServiceTokens.Serializer, options.serializer || new JsonSerializer())\n\tcontainer.register(ServiceTokens.Evaluator, options.evaluator || new PropertyEvaluator())\n\tcontainer.register(ServiceTokens.EventBus, options.eventBus || { emit: async () => {} })\n\tcontainer.register(ServiceTokens.Middleware, options.middleware || [])\n\tcontainer.register(ServiceTokens.NodeRegistry, options.registry || {})\n\tcontainer.register(ServiceTokens.BlueprintRegistry, options.blueprints || {})\n\tcontainer.register(ServiceTokens.Dependencies, options.dependencies || ({} as TDependencies))\n\n\tcontainer.registerFactory(ServiceTokens.Orchestrator, () => new DefaultOrchestrator())\n\n\treturn container\n}\n"]}
@@ -283,5 +283,5 @@ function createFlow(id) {
283
283
  }
284
284
 
285
285
  export { FlowBuilder, createFlow };
286
- //# sourceMappingURL=chunk-IWTFVGMK.js.map
287
- //# sourceMappingURL=chunk-IWTFVGMK.js.map
286
+ //# sourceMappingURL=chunk-AKDL2ZX7.js.map
287
+ //# sourceMappingURL=chunk-AKDL2ZX7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/flow.ts"],"names":[],"mappings":"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","file":"chunk-IWTFVGMK.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 FlowBuilder<\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): FlowBuilder<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\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\tthis.blueprint.nodes?.push({\n\t\t\tid: scatterId,\n\t\t\tuses: 'batch-scatter',\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\tthis.blueprint.nodes?.push({\n\t\t\tid: gatherId,\n\t\t\tuses: 'batch-gather',\n\t\t\tparams: { outputKey, gatherNodeId: gatherId },\n\t\t\tconfig: { joinStrategy: 'all' },\n\t\t})\n\n\t\tthis.edge(scatterId, gatherId)\n\n\t\treturn this as unknown as FlowBuilder<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\tthis.blueprint.nodes?.push({\n\t\t\tid: controllerId,\n\t\t\tuses: 'loop-controller',\n\t\t\tparams: { condition },\n\t\t\tconfig: { joinStrategy: 'any' },\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}`,\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\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): FlowBuilder<TContext, TDependencies> {\n\treturn new FlowBuilder(id)\n}\n"]}
1
+ {"version":3,"sources":["../src/flow.ts"],"names":[],"mappings":";;;AAMA,IAAI,WAAA,GAAc,CAAA;AAClB,SAAS,cAAc,EAAA,EAAwF;AAC9G,EAAA,MAAM,MAAA,GAAS,GAAG,QAAA,EAAS;AAC3B,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACvC,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,UAAA,CAAW,CAAC,CAAA;AAChC,IAAA,IAAA,GAAA,CAAQ,IAAA,IAAQ,KAAK,IAAA,GAAO,IAAA;AAC5B,IAAA,IAAA,GAAO,IAAA,GAAO,IAAA;AAAA,EACf;AAEA,EAAA,OAAA,CAAQ,KAAK,GAAA,CAAI,IAAI,CAAA,GAAI,WAAA,EAAA,EAAe,SAAS,EAAE,CAAA;AACpD;AAKO,IAAM,cAAN,MAGL;AAAA,EACO,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA,EAMA,gBAAA;AAAA,EAKA,gBAAA;AAAA,EAER,YAAY,EAAA,EAAY;AACvB,IAAA,IAAA,CAAK,SAAA,GAAY,EAAE,EAAA,EAAI,KAAA,EAAO,EAAC,EAAG,KAAA,EAAO,EAAC,EAAE;AAC5C,IAAA,IAAA,CAAK,gBAAA,uBAAuB,GAAA,EAAI;AAChC,IAAA,IAAA,CAAK,iBAAA,uBAAwB,GAAA,EAAI;AACjC,IAAA,IAAA,CAAK,kBAAkB,EAAC;AACxB,IAAA,IAAA,CAAK,mBAAmB,EAAC;AACzB,IAAA,IAAA,CAAK,gBAAA,uBAAuB,GAAA,EAAI;AAAA,EACjC;AAAA,EAEA,IAAA,CACC,EAAA,EACA,cAAA,EAGA,OAAA,EACO;AACP,IAAA,IAAI,OAAA;AAEJ,IAAA,IAAI,WAAA,CAAY,cAAc,CAAA,EAAG;AAChC,MAAA,OAAA,GACC,cAAA,CAAe,IAAA,IAAQ,cAAA,CAAe,IAAA,KAAS,UAAA,GAC5C,eAAe,IAAA,GACf,CAAA,MAAA,EAAS,aAAA,CAAc,cAAc,CAAC,CAAA,CAAA;AAC1C,MAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,OAAA,EAAS,cAAc,CAAA;AAAA,IAClD,CAAA,MAAO;AACN,MAAA,OAAA,GAAU,CAAA,GAAA,EAAM,aAAA,CAAc,cAAc,CAAC,CAAA,CAAA;AAC7C,MAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,OAAA,EAAS,cAAyC,CAAA;AAAA,IAC7E;AAEA,IAAA,MAAM,UAA0B,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,GAAG,OAAA,EAAQ;AAChE,IAAA,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAClC,IAAA,OAAO,IAAA;AAAA,EACR;AAAA,EAEA,IAAA,CAAK,MAAA,EAAgB,MAAA,EAAgB,OAAA,EAA2D;AAC/F,IAAA,MAAM,OAAA,GAA0B,EAAE,MAAA,EAAQ,MAAA,EAAQ,GAAG,OAAA,EAAQ;AAC7D,IAAA,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAClC,IAAA,OAAO,IAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,KAAA,CACC,EAAA,EACA,MAAA,EAGA,OAAA,EAQgF;AAChF,IAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,OAAA;AAChC,IAAA,MAAM,SAAA,GAAY,GAAG,EAAE,CAAA,QAAA,CAAA;AACvB,IAAA,MAAM,QAAA,GAAW,GAAG,EAAE,CAAA,OAAA,CAAA;AAEtB,IAAA,IAAA,CAAK,iBAAiB,IAAA,CAAK,EAAE,EAAA,EAAI,SAAA,EAAW,UAAU,CAAA;AAEtD,IAAA,IAAI,aAAA;AACJ,IAAA,IAAI,WAAA,CAAY,MAAM,CAAA,EAAG;AACxB,MAAA,aAAA,GACC,MAAA,CAAO,IAAA,IAAQ,MAAA,CAAO,IAAA,KAAS,UAAA,GAAa,OAAO,IAAA,GAAO,CAAA,mBAAA,EAAsB,aAAA,CAAc,MAAM,CAAC,CAAA,CAAA;AACtG,MAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,aAAA,EAAe,MAAM,CAAA;AAAA,IAChD,CAAA,MAAO;AACN,MAAA,aAAA,GAAgB,CAAA,gBAAA,EAAmB,aAAA,CAAc,MAAM,CAAC,CAAA,CAAA;AACxD,MAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,aAAA,EAAe,MAAiC,CAAA;AAAA,IAC3E;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,OAAO,IAAA,CAAK;AAAA,MAC1B,EAAA,EAAI,SAAA;AAAA,MACJ,IAAA,EAAM,eAAA;AAAA,MACN,MAAA,EAAQ,QAAA;AAAA,MACR,MAAA,EAAQ,EAAE,aAAA,EAAe,SAAA,EAAgC,cAAc,QAAA,EAAU,SAAA,EAAW,QAAQ,SAAA;AAAU,KAC9G,CAAA;AAED,IAAA,IAAA,CAAK,SAAA,CAAU,OAAO,IAAA,CAAK;AAAA,MAC1B,EAAA,EAAI,QAAA;AAAA,MACJ,IAAA,EAAM,cAAA;AAAA,MACN,MAAA,EAAQ,EAAE,SAAA,EAAW,YAAA,EAAc,QAAA,EAAS;AAAA,MAC5C,MAAA,EAAQ,EAAE,YAAA,EAAc,KAAA;AAAM,KAC9B,CAAA;AAED,IAAA,IAAA,CAAK,IAAA,CAAK,WAAW,QAAQ,CAAA;AAE7B,IAAA,OAAO,IAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAA,CACC,IACA,OAAA,EAIO;AACP,IAAA,MAAM,OAAA,GAA0B;AAAA,MAC/B,EAAA;AAAA,MACA,IAAA,EAAM,OAAA;AAAA,MACN,MAAA,EAAQ,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA;AAAS,KACtC;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAClC,IAAA,OAAO,IAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAA,CAAK,IAAY,OAAA,EAAqD;AACrE,IAAA,MAAM,UAA0B,EAAE,EAAA,EAAI,IAAA,EAAM,MAAA,EAAQ,GAAG,OAAA,EAAQ;AAC/D,IAAA,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAClC,IAAA,OAAO,IAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,IAAA,CACC,IACA,OAAA,EAQO;AACP,IAAA,MAAM,EAAE,WAAA,EAAa,SAAA,EAAW,SAAA,EAAU,GAAI,OAAA;AAC9C,IAAA,MAAM,YAAA,GAAe,GAAG,EAAE,CAAA,KAAA,CAAA;AAE1B,IAAA,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,EAAA,EAAI,YAAY,CAAA;AAE3C,IAAA,IAAA,CAAK,gBAAgB,IAAA,CAAK,EAAE,IAAI,WAAA,EAAa,SAAA,EAAW,WAAW,CAAA;AAEnE,IAAA,IAAA,CAAK,SAAA,CAAU,OAAO,IAAA,CAAK;AAAA,MAC1B,EAAA,EAAI,YAAA;AAAA,MACJ,IAAA,EAAM,iBAAA;AAAA,MACN,MAAA,EAAQ,EAAE,SAAA,EAAU;AAAA,MACpB,MAAA,EAAQ,EAAE,YAAA,EAAc,KAAA;AAAM,KAC9B,CAAA;AAED,IAAA,IAAA,CAAK,IAAA,CAAK,WAAW,YAAY,CAAA;AAEjC,IAAA,IAAA,CAAK,IAAA,CAAK,cAAc,WAAA,EAAa;AAAA,MACpC,MAAA,EAAQ,UAAA;AAAA,MACR,SAAA,EAAW,WAAW,SAAS,CAAA;AAAA,KAC/B,CAAA;AAED,IAAA,OAAO,IAAA;AAAA,EACR;AAAA,EAEA,oBAAoB,EAAA,EAAoB;AACvC,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,EAAE,CAAA;AAClD,IAAA,IAAI,CAAC,YAAA,EAAc;AAClB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,cAAA,EAAiB,EAAE,CAAA,iEAAA,CAAmE,CAAA;AAAA,IACvG;AACA,IAAA,OAAO,YAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB,MAAA,EAAsB;AACxC,IAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAA;AACxC,IAAA,OAAO,IAAA;AAAA,EACR;AAAA,EAEA,WAAA,GAAiC;AAChC,IAAA,IAAI,CAAC,KAAK,SAAA,CAAU,KAAA,IAAS,KAAK,SAAA,CAAU,KAAA,CAAM,WAAW,CAAA,EAAG;AAC/D,MAAA,MAAM,IAAI,MAAM,yCAAyC,CAAA;AAAA,IAC1D;AACA,IAAA,MAAM,aAA+B,EAAC;AACtC,IAAA,MAAM,sBAAA,uBAA6B,GAAA,EAAoB;AACvD,IAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,SAAA,CAAU,KAAA,IAAS,EAAC;AAGlD,IAAA,KAAA,MAAW,OAAA,IAAW,KAAK,eAAA,EAAiB;AAC3C,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,mBAAA,CAAoB,OAAA,CAAQ,EAAE,CAAA;AACxD,MAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,OAAA,CAAQ,SAAA,IAAa,CAAA,CAAE,MAAA,KAAW,YAAY,CAAA;AAChH,MAAA,KAAA,MAAW,QAAQ,aAAA,EAAe;AACjC,QAAA,UAAA,CAAW,IAAA,CAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,cAAc,MAAA,EAAQ,IAAA,CAAK,MAAA,IAAU,OAAA,EAAS,CAAA;AACjF,QAAA,sBAAA,CAAuB,IAAI,IAAI,CAAA;AAAA,MAChC;AAAA,IACD;AAGA,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,gBAAA,EAAkB;AAC7C,MAAA,MAAM,aAAA,GAAgB,iBAAiB,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,MAAA,KAAW,SAAS,EAAE,CAAA;AAC7E,MAAA,KAAA,MAAW,QAAQ,aAAA,EAAe;AACjC,QAAA,UAAA,CAAW,KAAK,EAAE,GAAG,MAAM,MAAA,EAAQ,QAAA,CAAS,WAAW,CAAA;AACvD,QAAA,sBAAA,CAAuB,IAAI,IAAI,CAAA;AAAA,MAChC;AAEA,MAAA,MAAM,aAAA,GAAgB,iBAAiB,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,MAAA,KAAW,SAAS,EAAE,CAAA;AAC7E,MAAA,KAAA,MAAW,QAAQ,aAAA,EAAe;AACjC,QAAA,UAAA,CAAW,KAAK,EAAE,GAAG,MAAM,MAAA,EAAQ,QAAA,CAAS,UAAU,CAAA;AACtD,QAAA,sBAAA,CAAuB,IAAI,IAAI,CAAA;AAAA,MAChC;AAAA,IACD;AAGA,IAAA,KAAA,MAAW,QAAQ,gBAAA,EAAkB;AACpC,MAAA,IAAI,CAAC,sBAAA,CAAuB,GAAA,CAAI,IAAI,CAAA,EAAG;AACtC,QAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,MACrB;AAAA,IACD;AACA,IAAA,IAAA,CAAK,UAAU,KAAA,GAAQ,UAAA;AAEvB,IAAA,KAAA,MAAW,OAAA,IAAW,KAAK,eAAA,EAAiB;AAC3C,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,OAAA,CAAQ,WAAW,CAAA;AAChF,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,OAAA,CAAQ,SAAS,CAAA;AAE5E,MAAA,IAAI,CAAC,SAAA,EAAW;AACf,QAAA,MAAM,IAAI,MAAM,CAAA,MAAA,EAAS,OAAA,CAAQ,EAAE,CAAA,sCAAA,EAAyC,OAAA,CAAQ,WAAW,CAAA,EAAA,CAAI,CAAA;AAAA,MACpG;AACA,MAAA,IAAI,CAAC,OAAA,EAAS;AACb,QAAA,MAAM,IAAI,MAAM,CAAA,MAAA,EAAS,OAAA,CAAQ,EAAE,CAAA,oCAAA,EAAuC,OAAA,CAAQ,SAAS,CAAA,EAAA,CAAI,CAAA;AAAA,MAChG;AAEA,MAAA,SAAA,CAAU,SAAS,EAAE,GAAG,SAAA,CAAU,MAAA,EAAQ,cAAc,KAAA,EAAM;AAC9D,MAAA,OAAA,CAAQ,SAAS,EAAE,GAAG,OAAA,CAAQ,MAAA,EAAQ,cAAc,KAAA,EAAM;AAAA,IAC3D;AAEA,IAAA,IAAI,IAAA,CAAK,gBAAA,CAAiB,IAAA,GAAO,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,UAAU,QAAA,GAAW;AAAA,QACzB,GAAG,KAAK,SAAA,CAAU,QAAA;AAAA,QAClB,kBAAkB,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,gBAAA,CAAiB,MAAM;AAAA,OAC1D;AAAA,IACD;AAEA,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACb;AAAA,EAEA,mBAAA,GAAsB;AACrB,IAAA,OAAO,IAAA,CAAK,gBAAA;AAAA,EACb;AAAA,EAEA,qBAAA,GAAiC;AAChC,IAAA,MAAM,SAAA,GAAY,KAAK,WAAA,EAAY;AACnC,IAAA,MAAM,UAA4B,EAAC;AACnC,IAAA,MAAM,UAA4B,EAAC;AAEnC,IAAA,MAAM,cAAA,uBAAqB,GAAA,EAAY;AAGvC,IAAA,KAAA,MAAW,OAAA,IAAW,KAAK,eAAA,EAAiB;AAC3C,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,QAAQ,EAAE,CAAA;AAC1D,MAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,MAAA,cAAA,CAAe,IAAI,YAAY,CAAA;AAG/B,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACZ,QAAQ,OAAA,CAAQ,SAAA;AAAA,QAChB,QAAQ,OAAA,CAAQ,WAAA;AAAA,QAChB,IAAA,EAAM;AAAA,UACL,UAAA,EAAY,IAAA;AAAA,UACZ,WAAW,OAAA,CAAQ,SAAA;AAAA,UACnB,KAAA,EAAO,CAAA,aAAA,EAAgB,OAAA,CAAQ,SAAS,CAAA;AAAA;AACzC,OACA,CAAA;AAGD,MAAA,MAAM,UAAA,GAAa,SAAA,CAAU,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,CAAK,MAAA,KAAW,YAAA,IAAgB,IAAA,CAAK,MAAA,KAAW,OAAO,CAAA;AAC3G,MAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AACnC,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACZ,GAAG,SAAA;AAAA,UACH,QAAQ,OAAA,CAAQ;AAAA,SAChB,CAAA;AAAA,MACF;AAAA,IACD;AAGA,IAAA,MAAM,YAAA,GAAe,UAAU,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,eAAe,CAAA;AAC7E,IAAA,KAAA,MAAW,eAAe,YAAA,EAAc;AACvC,MAAA,MAAM,YAAA,GAAe,YAAY,MAAA,EAAQ,YAAA;AACzC,MAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,MAAA,cAAA,CAAe,GAAA,CAAI,YAAY,EAAE,CAAA;AACjC,MAAA,cAAA,CAAe,IAAI,YAAY,CAAA;AAG/B,MAAA,MAAM,OAAA,GAAU,WAAA,CAAY,EAAA,CAAG,OAAA,CAAQ,YAAY,EAAE,CAAA;AACrD,MAAA,MAAM,UAAA,GAAa,UAAU,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,YAAY,CAAA;AAEpE,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACZ,EAAA,EAAI,OAAA;AAAA,QACJ,IAAA,EAAM,YAAY,MAAA,EAAQ,aAAA;AAAA,QAC1B,IAAA,EAAM,cAAA;AAAA,QACN,IAAA,EAAM;AAAA,UACL,KAAA,EAAO,UAAU,OAAO,CAAA,CAAA;AAAA,UACxB,kBAAA,EAAoB,IAAA;AAAA,UACpB,aAAA,EAAe,YAAY,MAAA,EAAQ,aAAA;AAAA,UACnC,UAAU,WAAA,CAAY,MAAA;AAAA,UACtB,SAAA,EAAW,YAAY,MAAA,EAAQ;AAAA;AAChC,OACA,CAAA;AAGD,MAAA,MAAM,aAAA,GAAgB,UAAU,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,WAAA,CAAY,EAAE,CAAA;AAC/E,MAAA,KAAA,MAAW,QAAQ,aAAA,EAAe;AACjC,QAAA,OAAA,CAAQ,KAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,SAAS,CAAA;AAAA,MAC1C;AAGA,MAAA,MAAM,aAAA,GAAgB,UAAU,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,YAAY,CAAA;AAC7E,MAAA,KAAA,MAAW,QAAQ,aAAA,EAAe;AACjC,QAAA,OAAA,CAAQ,KAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,SAAS,CAAA;AAAA,MAC1C;AAAA,IACD;AAEA,IAAA,KAAA,MAAW,IAAA,IAAQ,UAAU,KAAA,EAAO;AACnC,MAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG;AACjC,QAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,MAClB;AAAA,IACD;AAEA,IAAA,KAAA,MAAW,IAAA,IAAQ,UAAU,KAAA,EAAO;AACnC,MAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,IAAK,CAAC,cAAA,CAAe,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,EAAG;AACzE,QAAA,MAAM,eAAe,OAAA,CAAQ,IAAA;AAAA,UAC5B,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,IAAA,CAAK,MAAA,IAAU,CAAA,CAAE,MAAA,KAAW,IAAA,CAAK,MAAA,IAAU,CAAA,CAAE,MAAA,KAAW,IAAA,CAAK;AAAA,SAClF;AACA,QAAA,IAAI,CAAC,YAAA,EAAc;AAClB,UAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,QAClB;AAAA,MACD;AAAA,IACD;AAEA,IAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,EAAO,OAAA,EAAQ;AAAA,EACzC;AACD;AAKO,SAAS,WAGd,EAAA,EAAkD;AACnD,EAAA,OAAO,IAAI,YAAY,EAAE,CAAA;AAC1B","file":"chunk-AKDL2ZX7.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 FlowBuilder<\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): FlowBuilder<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\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\tthis.blueprint.nodes?.push({\n\t\t\tid: scatterId,\n\t\t\tuses: 'batch-scatter',\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\tthis.blueprint.nodes?.push({\n\t\t\tid: gatherId,\n\t\t\tuses: 'batch-gather',\n\t\t\tparams: { outputKey, gatherNodeId: gatherId },\n\t\t\tconfig: { joinStrategy: 'all' },\n\t\t})\n\n\t\tthis.edge(scatterId, gatherId)\n\n\t\treturn this as unknown as FlowBuilder<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 or a string like '5s', '1m', '2h', '1d'. */\n\t\t\tduration: number | string\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\tthis.blueprint.nodes?.push({\n\t\t\tid: controllerId,\n\t\t\tuses: 'loop-controller',\n\t\t\tparams: { condition },\n\t\t\tconfig: { joinStrategy: 'any' },\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}`,\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\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): FlowBuilder<TContext, TDependencies> {\n\treturn new FlowBuilder(id)\n}\n"]}
@@ -1,7 +1,7 @@
1
- import { StepByStepOrchestrator } from './chunk-C3ZT7FNO.js';
1
+ import { StepByStepOrchestrator } from './chunk-RAZWRNAJ.js';
2
2
  import { GraphTraverser } from './chunk-H4JTZYIT.js';
3
- import { ExecutionContext } from './chunk-N4NLAIEN.js';
4
- import { WorkflowState } from './chunk-5BOUGXZO.js';
3
+ import { ExecutionContext } from './chunk-L3MX5MTA.js';
4
+ import { WorkflowState } from './chunk-L46TQXCV.js';
5
5
 
6
6
  // src/testing/stepper.ts
7
7
  async function createStepper(runtime, blueprint, functionRegistry, initialState = {}) {
@@ -40,13 +40,13 @@ async function createStepper(runtime, blueprint, functionRegistry, initialState
40
40
  const previousStateData = runtime.serializer.deserialize(previousStateJson);
41
41
  state = new WorkflowState(previousStateData);
42
42
  traverser = GraphTraverser.fromState(_initialBlueprint, state);
43
- return state.toResult(runtime.serializer);
43
+ return state.toResult(runtime.serializer, void 0);
44
44
  },
45
45
  async next(options = {}) {
46
46
  if (stepper.isDone()) {
47
47
  return null;
48
48
  }
49
- const serializedContext = (await state.toResult(runtime.serializer)).serializedContext;
49
+ const serializedContext = (await state.toResult(runtime.serializer, void 0)).serializedContext;
50
50
  history.push(serializedContext);
51
51
  const executionContext = new ExecutionContext(
52
52
  _initialBlueprint,
@@ -72,5 +72,5 @@ async function createStepper(runtime, blueprint, functionRegistry, initialState
72
72
  }
73
73
 
74
74
  export { createStepper };
75
- //# sourceMappingURL=chunk-2YLGY3R2.js.map
76
- //# sourceMappingURL=chunk-2YLGY3R2.js.map
75
+ //# sourceMappingURL=chunk-BCMR7Y4U.js.map
76
+ //# sourceMappingURL=chunk-BCMR7Y4U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/stepper.ts"],"names":[],"mappings":"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","file":"chunk-BCMR7Y4U.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, undefined)\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, undefined)).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"]}