flowcraft 2.10.0 → 2.10.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 (127) hide show
  1. package/README.md +3 -3
  2. package/dist/adapter-DzeZVjSE.d.mts +133 -0
  3. package/dist/adapters/index.d.mts +2 -0
  4. package/dist/adapters/index.mjs +3 -0
  5. package/dist/adapters/persistent-event-bus.d.mts +2 -0
  6. package/dist/adapters/persistent-event-bus.mjs +59 -0
  7. package/dist/analysis-B5Twr7sD.d.mts +52 -0
  8. package/dist/analysis.d.mts +2 -0
  9. package/dist/analysis.mjs +164 -0
  10. package/dist/batch-gather-BhF-IzQR.d.mts +8 -0
  11. package/dist/batch-scatter-DD8TU0Wm.d.mts +8 -0
  12. package/dist/container-BKdd-9wf.d.mts +24 -0
  13. package/dist/container-factory-fDY2kkxt.d.mts +17 -0
  14. package/dist/container-factory.d.mts +2 -0
  15. package/dist/container-factory.mjs +23 -0
  16. package/dist/container.d.mts +2 -0
  17. package/dist/container.mjs +43 -0
  18. package/dist/context-ZVtzXuZu.d.mts +64 -0
  19. package/dist/context.d.mts +2 -0
  20. package/dist/context.mjs +145 -0
  21. package/dist/error-mapper-BAv_YQMQ.d.mts +14 -0
  22. package/dist/error-mapper.d.mts +2 -0
  23. package/dist/error-mapper.mjs +37 -0
  24. package/dist/errors-CyyIj3OO.d.mts +21 -0
  25. package/dist/errors.d.mts +2 -0
  26. package/dist/errors.mjs +24 -0
  27. package/dist/evaluator-Dnj5qJ92.d.mts +31 -0
  28. package/dist/evaluator.d.mts +2 -0
  29. package/dist/evaluator.mjs +80 -0
  30. package/dist/flow-CZGpYpl-.d.mts +94 -0
  31. package/dist/flow.d.mts +2 -0
  32. package/dist/flow.mjs +328 -0
  33. package/dist/index-9iG2qHLe.d.mts +1 -0
  34. package/dist/index-Bk0eNZmQ.d.mts +1 -0
  35. package/dist/index-CNgSR_kt.d.mts +1 -0
  36. package/dist/index-CW2WHUXP.d.mts +1 -0
  37. package/dist/index.d.mts +24 -1
  38. package/dist/index.mjs +31 -791
  39. package/dist/linter-B8KALEae.d.mts +25 -0
  40. package/dist/linter.d.mts +2 -0
  41. package/dist/linter.mjs +74 -0
  42. package/dist/logger-BvDgvNHQ.d.mts +19 -0
  43. package/dist/logger.d.mts +2 -0
  44. package/dist/logger.mjs +26 -0
  45. package/dist/node.d.mts +2 -0
  46. package/dist/node.mjs +55 -0
  47. package/dist/nodes/batch-gather.d.mts +2 -0
  48. package/dist/nodes/batch-gather.mjs +47 -0
  49. package/dist/nodes/batch-scatter.d.mts +2 -0
  50. package/dist/nodes/batch-scatter.mjs +52 -0
  51. package/dist/nodes/index.d.mts +7 -0
  52. package/dist/nodes/index.mjs +8 -0
  53. package/dist/nodes/sleep.d.mts +2 -0
  54. package/dist/nodes/sleep.mjs +41 -0
  55. package/dist/nodes/subflow.d.mts +2 -0
  56. package/dist/nodes/subflow.mjs +64 -0
  57. package/dist/nodes/wait.d.mts +2 -0
  58. package/dist/nodes/wait.mjs +12 -0
  59. package/dist/nodes/webhook.d.mts +2 -0
  60. package/dist/nodes/webhook.mjs +24 -0
  61. package/dist/orchestrator-DwMIJRFI.d.mts +8 -0
  62. package/dist/persistent-event-bus-COiQOpWh.d.mts +68 -0
  63. package/dist/replay-CVOy6d_L.d.mts +44 -0
  64. package/dist/runtime/adapter.d.mts +2 -0
  65. package/dist/runtime/adapter.mjs +349 -0
  66. package/dist/runtime/builtin-keys.d.mts +37 -0
  67. package/dist/runtime/builtin-keys.mjs +12 -0
  68. package/dist/runtime/execution-context.d.mts +2 -0
  69. package/dist/runtime/execution-context.mjs +26 -0
  70. package/dist/runtime/executors.d.mts +2 -0
  71. package/dist/runtime/executors.mjs +259 -0
  72. package/dist/runtime/index.d.mts +6 -0
  73. package/dist/runtime/index.mjs +10 -0
  74. package/dist/runtime/node-executor-factory.d.mts +11 -0
  75. package/dist/runtime/node-executor-factory.mjs +41 -0
  76. package/dist/runtime/orchestrator.d.mts +2 -0
  77. package/dist/runtime/orchestrator.mjs +41 -0
  78. package/dist/runtime/orchestrators/replay.d.mts +2 -0
  79. package/dist/{replay-BB11M6K1.mjs → runtime/orchestrators/replay.mjs} +1 -20
  80. package/dist/runtime/orchestrators/step-by-step.d.mts +15 -0
  81. package/dist/runtime/orchestrators/step-by-step.mjs +41 -0
  82. package/dist/runtime/orchestrators/utils.d.mts +2 -0
  83. package/dist/runtime/orchestrators/utils.mjs +79 -0
  84. package/dist/runtime/runtime.d.mts +2 -0
  85. package/dist/runtime/runtime.mjs +425 -0
  86. package/dist/runtime/scheduler.d.mts +2 -0
  87. package/dist/runtime/scheduler.mjs +64 -0
  88. package/dist/runtime/state.d.mts +2 -0
  89. package/dist/runtime/state.mjs +127 -0
  90. package/dist/runtime/traverser.d.mts +2 -0
  91. package/dist/runtime/traverser.mjs +213 -0
  92. package/dist/runtime/types.d.mts +2 -0
  93. package/dist/runtime/types.mjs +1 -0
  94. package/dist/runtime/workflow-logic-handler.d.mts +16 -0
  95. package/dist/runtime/workflow-logic-handler.mjs +159 -0
  96. package/dist/sanitizer-Bi00YjvO.d.mts +11 -0
  97. package/dist/sanitizer.d.mts +2 -0
  98. package/dist/sanitizer.mjs +37 -0
  99. package/dist/sdk.d.mts +1 -2
  100. package/dist/sdk.mjs +1 -2
  101. package/dist/serializer-BnmJr13R.d.mts +17 -0
  102. package/dist/serializer.d.mts +2 -0
  103. package/dist/serializer.mjs +34 -0
  104. package/dist/sleep-DpwYaY5b.d.mts +8 -0
  105. package/dist/subflow-n2IMsRe2.d.mts +8 -0
  106. package/dist/testing/event-logger.d.mts +62 -0
  107. package/dist/testing/event-logger.mjs +98 -0
  108. package/dist/testing/index.d.mts +5 -172
  109. package/dist/testing/index.mjs +6 -276
  110. package/dist/testing/run-with-trace.d.mts +37 -0
  111. package/dist/testing/run-with-trace.mjs +49 -0
  112. package/dist/testing/stepper.d.mts +78 -0
  113. package/dist/testing/stepper.mjs +100 -0
  114. package/dist/types-BcrXJEPI.d.mts +687 -0
  115. package/dist/types.d.mts +2 -0
  116. package/dist/types.mjs +1 -0
  117. package/dist/utils-BUEgr9V2.d.mts +34 -0
  118. package/dist/wait-2Q-LA7V7.d.mts +8 -0
  119. package/dist/webhook-BiCm-HLx.d.mts +12 -0
  120. package/package.json +4 -4
  121. package/dist/index-BXRN44Qf.d.mts +0 -1347
  122. package/dist/index.mjs.map +0 -1
  123. package/dist/replay-BB11M6K1.mjs.map +0 -1
  124. package/dist/runtime-ChsWirQN.mjs +0 -2256
  125. package/dist/runtime-ChsWirQN.mjs.map +0 -1
  126. package/dist/sdk.mjs.map +0 -1
  127. package/dist/testing/index.mjs.map +0 -1
@@ -0,0 +1,25 @@
1
+ import { d as NodeClass, h as NodeFunction, w as WorkflowBlueprint } from "./types-BcrXJEPI.mjs";
2
+
3
+ //#region src/linter.d.ts
4
+ type LinterIssueCode = 'INVALID_EDGE_SOURCE' | 'INVALID_EDGE_TARGET' | 'MISSING_NODE_IMPLEMENTATION' | 'ORPHAN_NODE' | 'INVALID_BATCH_WORKER_KEY' | 'INVALID_SUBFLOW_BLUEPRINT_ID';
5
+ interface LinterIssue {
6
+ code: LinterIssueCode;
7
+ message: string;
8
+ nodeId?: string;
9
+ relatedId?: string;
10
+ }
11
+ interface LinterResult {
12
+ isValid: boolean;
13
+ issues: LinterIssue[];
14
+ }
15
+ /**
16
+ * Statically analyzes a workflow blueprint against a registry of implementations
17
+ * to find common errors before runtime.
18
+ *
19
+ * @param blueprint The WorkflowBlueprint to analyze.
20
+ * @param registry A map of node implementations (functions or classes) to check against.
21
+ * @returns A LinterResult object containing any issues found.
22
+ */
23
+ declare function lintBlueprint(blueprint: WorkflowBlueprint, registry: Map<string, NodeFunction | NodeClass> | Record<string, NodeFunction | NodeClass>, blueprints?: Record<string, WorkflowBlueprint>): LinterResult;
24
+ //#endregion
25
+ export { lintBlueprint as i, LinterIssueCode as n, LinterResult as r, LinterIssue as t };
@@ -0,0 +1,2 @@
1
+ import { i as lintBlueprint, n as LinterIssueCode, r as LinterResult, t as LinterIssue } from "./linter-B8KALEae.mjs";
2
+ export { LinterIssue, LinterIssueCode, LinterResult, lintBlueprint };
@@ -0,0 +1,74 @@
1
+ import { analyzeBlueprint } from "./analysis.mjs";
2
+
3
+ //#region src/linter.ts
4
+ /**
5
+ * Statically analyzes a workflow blueprint against a registry of implementations
6
+ * to find common errors before runtime.
7
+ *
8
+ * @param blueprint The WorkflowBlueprint to analyze.
9
+ * @param registry A map of node implementations (functions or classes) to check against.
10
+ * @returns A LinterResult object containing any issues found.
11
+ */
12
+ function lintBlueprint(blueprint, registry, blueprints) {
13
+ const issues = [];
14
+ const nodeIds = new Set(blueprint.nodes.map((n) => n.id));
15
+ const registryKeys = registry instanceof Map ? new Set(registry.keys()) : new Set(Object.keys(registry));
16
+ for (const node of blueprint.nodes) if (!node.uses.startsWith("batch-") && !node.uses.startsWith("loop-") && !registryKeys.has(node.uses)) issues.push({
17
+ code: "MISSING_NODE_IMPLEMENTATION",
18
+ message: `Node implementation key '${node.uses}' is not found in the provided registry.`,
19
+ nodeId: node.id
20
+ });
21
+ for (const node of blueprint.nodes) {
22
+ if (node.uses.startsWith("batch-") && node.params?.workerUsesKey) {
23
+ if (!registryKeys.has(node.params.workerUsesKey)) issues.push({
24
+ code: "INVALID_BATCH_WORKER_KEY",
25
+ message: `Batch node '${node.id}' references workerUsesKey '${node.params.workerUsesKey}' which is not found in the registry.`,
26
+ nodeId: node.id
27
+ });
28
+ }
29
+ if (node.uses === "subflow" && node.params?.blueprintId) {
30
+ if (!blueprints?.[node.params.blueprintId]) issues.push({
31
+ code: "INVALID_SUBFLOW_BLUEPRINT_ID",
32
+ message: `Subflow node '${node.id}' references blueprintId '${node.params.blueprintId}' which is not found in the blueprints registry.`,
33
+ nodeId: node.id
34
+ });
35
+ }
36
+ }
37
+ for (const edge of blueprint.edges || []) {
38
+ if (!nodeIds.has(edge.source)) issues.push({
39
+ code: "INVALID_EDGE_SOURCE",
40
+ message: `Edge source '${edge.source}' does not correspond to a valid node ID.`,
41
+ relatedId: edge.target
42
+ });
43
+ if (!nodeIds.has(edge.target)) issues.push({
44
+ code: "INVALID_EDGE_TARGET",
45
+ message: `Edge target '${edge.target}' does not correspond to a valid node ID.`,
46
+ relatedId: edge.source
47
+ });
48
+ }
49
+ if (blueprint.nodes.length > 1) {
50
+ const analysis = analyzeBlueprint(blueprint);
51
+ const connectedNodes = /* @__PURE__ */ new Set();
52
+ const nodesToVisit = [...analysis.startNodeIds];
53
+ const visited = /* @__PURE__ */ new Set();
54
+ while (nodesToVisit.length > 0) {
55
+ const currentId = nodesToVisit.pop();
56
+ if (!currentId || visited.has(currentId)) continue;
57
+ visited.add(currentId);
58
+ connectedNodes.add(currentId);
59
+ for (const targetEdge of blueprint.edges.filter((e) => e.source === currentId)) nodesToVisit.push(targetEdge.target);
60
+ }
61
+ for (const nodeId of nodeIds) if (!connectedNodes.has(nodeId)) issues.push({
62
+ code: "ORPHAN_NODE",
63
+ message: `Node '${nodeId}' is not reachable from any start node.`,
64
+ nodeId
65
+ });
66
+ }
67
+ return {
68
+ isValid: issues.length === 0,
69
+ issues
70
+ };
71
+ }
72
+
73
+ //#endregion
74
+ export { lintBlueprint };
@@ -0,0 +1,19 @@
1
+ import { s as ILogger } from "./types-BcrXJEPI.mjs";
2
+
3
+ //#region src/logger.d.ts
4
+ /** A logger implementation that outputs to the console. */
5
+ declare class ConsoleLogger implements ILogger {
6
+ debug(message: string, meta?: Record<string, any>): void;
7
+ info(message: string, meta?: Record<string, any>): void;
8
+ warn(message: string, meta?: Record<string, any>): void;
9
+ error(message: string, meta?: Record<string, any>): void;
10
+ }
11
+ /** A logger implementation that does nothing (no-op). */
12
+ declare class NullLogger implements ILogger {
13
+ debug(_message: string, _meta?: Record<string, any>): void;
14
+ info(_message: string, _meta?: Record<string, any>): void;
15
+ warn(_message: string, _meta?: Record<string, any>): void;
16
+ error(_message: string, _meta?: Record<string, any>): void;
17
+ }
18
+ //#endregion
19
+ export { NullLogger as n, ConsoleLogger as t };
@@ -0,0 +1,2 @@
1
+ import { n as NullLogger, t as ConsoleLogger } from "./logger-BvDgvNHQ.mjs";
2
+ export { ConsoleLogger, NullLogger };
@@ -0,0 +1,26 @@
1
+ //#region src/logger.ts
2
+ /** A logger implementation that outputs to the console. */
3
+ var ConsoleLogger = class {
4
+ debug(message, meta) {
5
+ console.debug(`[DEBUG] ${message}`, meta || "");
6
+ }
7
+ info(message, meta) {
8
+ console.info(`[INFO] ${message}`, meta || "");
9
+ }
10
+ warn(message, meta) {
11
+ console.warn(`[WARN] ${message}`, meta || "");
12
+ }
13
+ error(message, meta) {
14
+ console.error(`[ERROR] ${message}`, meta || "");
15
+ }
16
+ };
17
+ /** A logger implementation that does nothing (no-op). */
18
+ var NullLogger = class {
19
+ debug(_message, _meta) {}
20
+ info(_message, _meta) {}
21
+ warn(_message, _meta) {}
22
+ error(_message, _meta) {}
23
+ };
24
+
25
+ //#endregion
26
+ export { ConsoleLogger, NullLogger };
@@ -0,0 +1,2 @@
1
+ import { K as BaseNode, q as isNodeClass } from "./types-BcrXJEPI.mjs";
2
+ export { BaseNode, isNodeClass };
package/dist/node.mjs ADDED
@@ -0,0 +1,55 @@
1
+ //#region src/node.ts
2
+ /** A type guard to reliably distinguish a NodeClass from a NodeFunction. */
3
+ function isNodeClass(impl) {
4
+ return typeof impl === "function" && !!impl.prototype?.exec;
5
+ }
6
+ /**
7
+ * A structured, class-based node for complex logic with a safe, granular lifecycle.
8
+ * This class is generic, allowing implementations to specify the exact context
9
+ * and dependency types they expect.
10
+ */
11
+ var BaseNode = class {
12
+ /**
13
+ * @param params Static parameters for this node instance, passed from the blueprint.
14
+ * @param nodeId The ID of the node in the blueprint.
15
+ */
16
+ constructor(params, nodeId) {
17
+ this.params = params;
18
+ this.nodeId = nodeId;
19
+ }
20
+ /**
21
+ * Phase 1: Gathers and prepares data for execution. This phase is NOT retried on failure.
22
+ * @param context The node's execution context.
23
+ * @returns The data needed for the `exec` phase.
24
+ */
25
+ async prep(context) {
26
+ return context.input;
27
+ }
28
+ /**
29
+ * Phase 3: Processes the result and saves state. This phase is NOT retried.
30
+ * @param execResult The successful result from the `exec` or `fallback` phase.
31
+ * @param _context The node's execution context.
32
+ */
33
+ async post(execResult, _context) {
34
+ return execResult;
35
+ }
36
+ /**
37
+ * An optional safety net that runs if all `exec` retries fail.
38
+ * @param error The final error from the last `exec` attempt.
39
+ * @param _context The node's execution context.
40
+ */
41
+ async fallback(error, _context) {
42
+ throw error;
43
+ }
44
+ /**
45
+ * An optional cleanup phase for non-retriable errors that occur outside the main `exec` method.
46
+ * This method is invoked in a `finally` block or equivalent construct if a fatal, unhandled exception occurs in the `prep`, `exec`, or `post` phases.
47
+ * Allows nodes to perform crucial cleanup, such as closing database connections or releasing locks.
48
+ * @param _error The error that caused the failure.
49
+ * @param _context The node's execution context.
50
+ */
51
+ async recover(_error, _context) {}
52
+ };
53
+
54
+ //#endregion
55
+ export { BaseNode, isNodeClass };
@@ -0,0 +1,2 @@
1
+ import { t as BatchGatherNode } from "../batch-gather-BhF-IzQR.mjs";
2
+ export { BatchGatherNode };
@@ -0,0 +1,47 @@
1
+ import { BaseNode } from "../node.mjs";
2
+
3
+ //#region src/nodes/batch-gather.ts
4
+ var BatchGatherNode = class extends BaseNode {
5
+ async exec(_prepResult, context) {
6
+ const { gatherNodeId, outputKey } = this.params || {};
7
+ const hasMore = await context.context.get(`${gatherNodeId}_hasMore`) || false;
8
+ const dynamicNodes = [];
9
+ let results = [];
10
+ if (hasMore) {
11
+ const newScatterId = `${gatherNodeId}_scatter_next`;
12
+ dynamicNodes.push({
13
+ id: newScatterId,
14
+ uses: "batch-scatter",
15
+ inputs: context.input,
16
+ params: {
17
+ ...this.params,
18
+ gatherNodeId
19
+ }
20
+ });
21
+ } else {
22
+ const allWorkerIds = await context.context.get(`${gatherNodeId}_allWorkerIds`) || [];
23
+ results = [];
24
+ for (const workerId of allWorkerIds) {
25
+ const result = await context.context.get(`_outputs.${workerId}`);
26
+ if (result !== void 0) results.push(result);
27
+ }
28
+ await context.context.set(outputKey, results);
29
+ const parentBatchId = gatherNodeId.replace("_gather", "");
30
+ await context.dependencies.runtime.services.eventBus.emit({
31
+ type: "batch:finish",
32
+ payload: {
33
+ batchId: parentBatchId,
34
+ gatherNodeId,
35
+ results
36
+ }
37
+ });
38
+ }
39
+ return {
40
+ dynamicNodes,
41
+ output: results
42
+ };
43
+ }
44
+ };
45
+
46
+ //#endregion
47
+ export { BatchGatherNode };
@@ -0,0 +1,2 @@
1
+ import { t as BatchScatterNode } from "../batch-scatter-DD8TU0Wm.mjs";
2
+ export { BatchScatterNode };
@@ -0,0 +1,52 @@
1
+ import { BaseNode } from "../node.mjs";
2
+
3
+ //#region src/nodes/batch-scatter.ts
4
+ var BatchScatterNode = class extends BaseNode {
5
+ async exec(_prepResult, context) {
6
+ const inputArray = context.input || [];
7
+ if (!Array.isArray(inputArray)) throw new Error(`Input for batch-scatter node '${this.nodeId}' must be an array.`);
8
+ const { chunkSize = inputArray.length, workerUsesKey, gatherNodeId } = this.params || {};
9
+ if (!workerUsesKey || !gatherNodeId) throw new Error(`BatchScatterNode requires 'workerUsesKey' and 'gatherNodeId' parameters.`);
10
+ const batchId = globalThis.crypto.randomUUID();
11
+ const currentIndex = await context.context.get(`${this.nodeId}_currentIndex`) || 0;
12
+ const endIndex = Math.min(currentIndex + chunkSize, inputArray.length);
13
+ const dynamicNodes = [];
14
+ const workerIds = [];
15
+ for (let i = currentIndex; i < endIndex; i++) {
16
+ const item = inputArray[i];
17
+ const itemInputKey = `_batch.${this.nodeId}_${batchId}_item_${i}`;
18
+ await context.context.set(itemInputKey, item);
19
+ const workerId = `${workerUsesKey}_${batchId}_${i}`;
20
+ workerIds.push(workerId);
21
+ dynamicNodes.push({
22
+ id: workerId,
23
+ uses: workerUsesKey,
24
+ inputs: itemInputKey
25
+ });
26
+ }
27
+ const parentBatchId = this.nodeId?.replace("_scatter", "") || "";
28
+ await context.dependencies.runtime.services.eventBus.emit({
29
+ type: "batch:start",
30
+ payload: {
31
+ batchId: parentBatchId,
32
+ scatterNodeId: this.nodeId,
33
+ workerNodeIds: workerIds
34
+ }
35
+ });
36
+ await context.context.set(`${this.nodeId}_currentIndex`, endIndex);
37
+ const hasMore = endIndex < inputArray.length;
38
+ await context.context.set(`${gatherNodeId}_hasMore`, hasMore);
39
+ const allWorkerIds = [...await context.context.get(`${gatherNodeId}_allWorkerIds`) || [], ...workerIds];
40
+ await context.context.set(`${gatherNodeId}_allWorkerIds`, allWorkerIds);
41
+ return {
42
+ dynamicNodes,
43
+ output: {
44
+ gatherNodeId,
45
+ hasMore
46
+ }
47
+ };
48
+ }
49
+ };
50
+
51
+ //#endregion
52
+ export { BatchScatterNode };
@@ -0,0 +1,7 @@
1
+ import { t as BatchGatherNode } from "../batch-gather-BhF-IzQR.mjs";
2
+ import { t as BatchScatterNode } from "../batch-scatter-DD8TU0Wm.mjs";
3
+ import { t as SleepNode } from "../sleep-DpwYaY5b.mjs";
4
+ import { t as SubflowNode } from "../subflow-n2IMsRe2.mjs";
5
+ import { t as WaitNode } from "../wait-2Q-LA7V7.mjs";
6
+ import { t as WebhookNode } from "../webhook-BiCm-HLx.mjs";
7
+ export { BatchGatherNode, BatchScatterNode, SleepNode, SubflowNode, WaitNode, WebhookNode };
@@ -0,0 +1,8 @@
1
+ import { BatchGatherNode } from "./batch-gather.mjs";
2
+ import { BatchScatterNode } from "./batch-scatter.mjs";
3
+ import { SleepNode } from "./sleep.mjs";
4
+ import { SubflowNode } from "./subflow.mjs";
5
+ import { WaitNode } from "./wait.mjs";
6
+ import { WebhookNode } from "./webhook.mjs";
7
+
8
+ export { BatchGatherNode, BatchScatterNode, SleepNode, SubflowNode, WaitNode, WebhookNode };
@@ -0,0 +1,2 @@
1
+ import { t as SleepNode } from "../sleep-DpwYaY5b.mjs";
2
+ export { SleepNode };
@@ -0,0 +1,41 @@
1
+ import { BaseNode } from "../node.mjs";
2
+
3
+ //#region src/nodes/sleep.ts
4
+ var SleepNode = class extends BaseNode {
5
+ async exec(prepResult, context) {
6
+ const durationParam = this.params?.duration;
7
+ let durationMs;
8
+ if (typeof durationParam === "string") {
9
+ const match = durationParam.match(/^(\d+)([smhd])$/);
10
+ if (!match) throw new Error(`SleepNode '${this.nodeId}' received an invalid duration string: '${durationParam}'. Expected format: '5m', '10s', '1h', '2d'`);
11
+ const [, numStr, unit] = match;
12
+ const num = parseInt(numStr, 10);
13
+ switch (unit) {
14
+ case "s":
15
+ durationMs = num * 1e3;
16
+ break;
17
+ case "m":
18
+ durationMs = num * 60 * 1e3;
19
+ break;
20
+ case "h":
21
+ durationMs = num * 60 * 60 * 1e3;
22
+ break;
23
+ case "d":
24
+ durationMs = num * 24 * 60 * 60 * 1e3;
25
+ break;
26
+ default: throw new Error(`Invalid duration unit: ${unit}`);
27
+ }
28
+ } else if (typeof durationParam === "number") durationMs = durationParam;
29
+ else throw new Error(`SleepNode '${this.nodeId}' received an invalid duration type: ${typeof durationParam}`);
30
+ if (durationMs < 0) throw new Error(`SleepNode '${this.nodeId}' received a negative duration.`);
31
+ const wakeUpAt = new Date(Date.now() + durationMs).toISOString();
32
+ await context.dependencies.workflowState.markAsAwaiting(this.nodeId ?? "", {
33
+ reason: "timer",
34
+ wakeUpAt
35
+ });
36
+ return { output: prepResult };
37
+ }
38
+ };
39
+
40
+ //#endregion
41
+ export { SleepNode };
@@ -0,0 +1,2 @@
1
+ import { t as SubflowNode } from "../subflow-n2IMsRe2.mjs";
2
+ export { SubflowNode };
@@ -0,0 +1,64 @@
1
+ import { analyzeBlueprint } from "../analysis.mjs";
2
+ import { FlowcraftError } from "../errors.mjs";
3
+ import { WorkflowState } from "../runtime/state.mjs";
4
+ import { ExecutionContext } from "../runtime/execution-context.mjs";
5
+ import { BaseNode } from "../node.mjs";
6
+ import { GraphTraverser } from "../runtime/traverser.mjs";
7
+
8
+ //#region src/nodes/subflow.ts
9
+ var SubflowNode = class extends BaseNode {
10
+ async exec(_prepResult, context) {
11
+ const { blueprintId, inputs, outputs } = this.params ?? {};
12
+ const { runtime, workflowState } = context.dependencies;
13
+ if (!blueprintId) throw new FlowcraftError(`Subflow node '${this.nodeId}' is missing 'blueprintId' parameter.`, { isFatal: true });
14
+ const subBlueprint = runtime.blueprints?.[blueprintId] || runtime.runtime?.blueprints?.[blueprintId];
15
+ if (!subBlueprint) throw new FlowcraftError(`Sub-blueprint '${blueprintId}' not found in runtime registry.`, { isFatal: true });
16
+ const subflowInitialContext = {};
17
+ if (inputs) for (const [targetKey, sourceKey] of Object.entries(inputs)) {
18
+ let value = await context.context.get(sourceKey);
19
+ if (value === void 0) value = await context.context.get(`_outputs.${sourceKey}`);
20
+ subflowInitialContext[targetKey] = value;
21
+ }
22
+ else if (context.input !== void 0) {
23
+ const subAnalysis = analyzeBlueprint(subBlueprint);
24
+ for (const startNodeId of subAnalysis.startNodeIds) {
25
+ const inputKey = `_inputs.${startNodeId}`;
26
+ subflowInitialContext[inputKey] = context.input;
27
+ }
28
+ }
29
+ const subflowExecContext = new ExecutionContext(subBlueprint, new WorkflowState(subflowInitialContext), runtime.nodeRegistry, runtime.executionId, runtime.runtime, runtime.services, runtime.signal, runtime.concurrency);
30
+ const subflowTraverser = new GraphTraverser(subBlueprint);
31
+ const subflowResult = await runtime.runtime.orchestrator.run(subflowExecContext, subflowTraverser);
32
+ if (subflowResult.status === "awaiting") {
33
+ await workflowState.markAsAwaiting(this.nodeId ?? "");
34
+ const subflowStateKey = `_subflowState.${this.nodeId}`;
35
+ await context.context.set(subflowStateKey, subflowResult.serializedContext);
36
+ return { output: void 0 };
37
+ }
38
+ if (subflowResult.status !== "completed") {
39
+ const firstError = subflowResult.errors?.[0];
40
+ const errorMessage = firstError?.message || "Unknown error";
41
+ throw new FlowcraftError(`Sub-workflow '${blueprintId}' did not complete successfully. Status: ${subflowResult.status}. Error: ${errorMessage}`, {
42
+ cause: firstError,
43
+ nodeId: this.nodeId,
44
+ blueprintId
45
+ });
46
+ }
47
+ const subflowFinalContext = subflowResult.context;
48
+ if (outputs) {
49
+ for (const [parentKey, subKey] of Object.entries(outputs)) {
50
+ const value = subflowFinalContext[`_outputs.${subKey}`] ?? subflowFinalContext[subKey];
51
+ await context.context.set(parentKey, value);
52
+ }
53
+ return { output: subflowFinalContext };
54
+ }
55
+ const subAnalysis = analyzeBlueprint(subBlueprint);
56
+ if (subAnalysis.terminalNodeIds.length === 1) return { output: subflowFinalContext[`_outputs.${subAnalysis.terminalNodeIds[0]}`] };
57
+ const terminalOutputs = {};
58
+ for (const terminalId of subAnalysis.terminalNodeIds) terminalOutputs[terminalId] = subflowFinalContext[`_outputs.${terminalId}`];
59
+ return { output: terminalOutputs };
60
+ }
61
+ };
62
+
63
+ //#endregion
64
+ export { SubflowNode };
@@ -0,0 +1,2 @@
1
+ import { t as WaitNode } from "../wait-2Q-LA7V7.mjs";
2
+ export { WaitNode };
@@ -0,0 +1,12 @@
1
+ import { BaseNode } from "../node.mjs";
2
+
3
+ //#region src/nodes/wait.ts
4
+ var WaitNode = class extends BaseNode {
5
+ async exec(_prepResult, context) {
6
+ await context.dependencies.workflowState.markAsAwaiting(this.nodeId ?? "", { reason: "external_event" });
7
+ return { output: void 0 };
8
+ }
9
+ };
10
+
11
+ //#endregion
12
+ export { WaitNode };
@@ -0,0 +1,2 @@
1
+ import { t as WebhookNode } from "../webhook-BiCm-HLx.mjs";
2
+ export { WebhookNode };
@@ -0,0 +1,24 @@
1
+ import { BaseNode } from "../node.mjs";
2
+
3
+ //#region src/nodes/webhook.ts
4
+ var WebhookNode = class extends BaseNode {
5
+ async prep(context) {
6
+ const runId = context.dependencies.runtime.executionId;
7
+ const nodeId = this.nodeId ?? "";
8
+ const { url, event } = await context.dependencies.adapter.registerWebhookEndpoint(runId, nodeId);
9
+ return {
10
+ url,
11
+ event
12
+ };
13
+ }
14
+ async exec(prepResult, _context) {
15
+ return { output: {
16
+ url: prepResult.url,
17
+ event: prepResult.event,
18
+ request: new Promise(() => {})
19
+ } };
20
+ }
21
+ };
22
+
23
+ //#endregion
24
+ export { WebhookNode };
@@ -0,0 +1,8 @@
1
+ import { D as WorkflowResult, F as GraphTraverser, M as IOrchestrator, k as ExecutionContext } from "./types-BcrXJEPI.mjs";
2
+
3
+ //#region src/runtime/orchestrator.d.ts
4
+ declare class DefaultOrchestrator implements IOrchestrator {
5
+ run(context: ExecutionContext<any, any>, traverser: GraphTraverser): Promise<WorkflowResult<any>>;
6
+ }
7
+ //#endregion
8
+ export { DefaultOrchestrator as t };
@@ -0,0 +1,68 @@
1
+ import { o as IEventBus, r as FlowcraftEvent } from "./types-BcrXJEPI.mjs";
2
+
3
+ //#region src/adapters/persistent-event-bus.d.ts
4
+ /**
5
+ * Interface for a persistent storage mechanism for events.
6
+ * Implementations can store events in databases, log streams, files, etc.
7
+ */
8
+ interface IEventStore {
9
+ /**
10
+ * Store an event persistently.
11
+ * @param event The event to store
12
+ * @param executionId The execution ID for grouping events
13
+ */
14
+ store(event: FlowcraftEvent, executionId: string): Promise<void>;
15
+ /**
16
+ * Retrieve all events for a specific execution.
17
+ * @param executionId The execution ID
18
+ * @returns Array of events in chronological order
19
+ */
20
+ retrieve(executionId: string): Promise<FlowcraftEvent[]>;
21
+ /**
22
+ * Retrieve events for multiple executions.
23
+ * @param executionIds Array of execution IDs
24
+ * @returns Map of execution ID to array of events
25
+ */
26
+ retrieveMultiple(executionIds: string[]): Promise<Map<string, FlowcraftEvent[]>>;
27
+ }
28
+ /**
29
+ * A pluggable event bus adapter that persists all workflow events
30
+ * to a configurable storage backend, enabling time-travel debugging and replay.
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // Using a database-backed store
35
+ * const eventStore = new DatabaseEventStore(dbConnection)
36
+ * const eventBus = new PersistentEventBusAdapter(eventStore)
37
+ * const runtime = new FlowRuntime({ eventBus })
38
+ *
39
+ * // Later, replay the execution
40
+ * const events = await eventStore.retrieve(executionId)
41
+ * const finalState = await runtime.replay(blueprint, events)
42
+ * ```
43
+ */
44
+ declare class PersistentEventBusAdapter implements IEventBus {
45
+ private store;
46
+ constructor(store: IEventStore);
47
+ /**
48
+ * Emit an event by storing it persistently.
49
+ * Also emits to console for debugging (can be made configurable).
50
+ */
51
+ emit(event: FlowcraftEvent): Promise<void>;
52
+ }
53
+ /**
54
+ * Simple in-memory event store for testing and development.
55
+ * Not suitable for production use.
56
+ */
57
+ declare class InMemoryEventStore implements IEventStore {
58
+ private events;
59
+ store(event: FlowcraftEvent, executionId: string): Promise<void>;
60
+ retrieve(executionId: string): Promise<FlowcraftEvent[]>;
61
+ retrieveMultiple(executionIds: string[]): Promise<Map<string, FlowcraftEvent[]>>;
62
+ /**
63
+ * Clear all stored events (useful for testing).
64
+ */
65
+ clear(): void;
66
+ }
67
+ //#endregion
68
+ export { InMemoryEventStore as n, PersistentEventBusAdapter as r, IEventStore as t };
@@ -0,0 +1,44 @@
1
+ import { D as WorkflowResult, F as GraphTraverser, M as IOrchestrator, k as ExecutionContext, r as FlowcraftEvent } from "./types-BcrXJEPI.mjs";
2
+
3
+ //#region src/runtime/orchestrators/replay.d.ts
4
+ /**
5
+ * An orchestrator that replays a pre-recorded sequence of workflow events
6
+ * to reconstruct the workflow state without executing any node logic.
7
+ *
8
+ * This enables time-travel debugging by allowing developers to inspect
9
+ * the exact state of a workflow at any point in its execution history.
10
+ */
11
+ declare class ReplayOrchestrator implements IOrchestrator {
12
+ private events;
13
+ /**
14
+ * Creates a new ReplayOrchestrator with a sequence of recorded workflow events.
15
+ *
16
+ * @param events - Array of FlowcraftEvent objects representing the recorded workflow execution
17
+ */
18
+ constructor(events: FlowcraftEvent[]);
19
+ /**
20
+ * Replays the recorded workflow events to reconstruct the workflow state.
21
+ *
22
+ * This method filters events for the specific execution, applies each event in sequence
23
+ * to rebuild the context state, and returns the final reconstructed workflow result.
24
+ * Replayed executions always have a "completed" status since they reconstruct the final state.
25
+ *
26
+ * @param context - The execution context containing state and services
27
+ * @param _traverser - Graph traverser (unused in replay mode)
28
+ * @returns Promise resolving to the reconstructed workflow result
29
+ */
30
+ run(context: ExecutionContext<any, any>, _traverser: GraphTraverser): Promise<WorkflowResult<any>>;
31
+ /**
32
+ * Applies a single workflow event to reconstruct the execution state.
33
+ *
34
+ * This method handles different event types by updating the workflow state accordingly,
35
+ * including node completions, context changes, errors, fallbacks, and workflow control events.
36
+ *
37
+ * @param event - The workflow event to apply
38
+ * @param context - The execution context to update
39
+ * @param fallbackMap - Map tracking fallback node relationships (fallbackNodeId -> originalNodeId)
40
+ */
41
+ private applyEvent;
42
+ }
43
+ //#endregion
44
+ export { ReplayOrchestrator as t };
@@ -0,0 +1,2 @@
1
+ import { i as JobPayload, n as BaseDistributedAdapter, r as ICoordinationStore, t as AdapterOptions } from "../adapter-DzeZVjSE.mjs";
2
+ export { AdapterOptions, BaseDistributedAdapter, ICoordinationStore, JobPayload };