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.
- package/dist/adapters/index.d.ts +4 -0
- package/dist/adapters/index.js +4 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/persistent-event-bus.d.ts +69 -0
- package/dist/adapters/persistent-event-bus.js +3 -0
- package/dist/adapters/persistent-event-bus.js.map +1 -0
- package/dist/analysis.d.ts +1 -1
- package/dist/chunk-2TSADFQX.js +46 -0
- package/dist/chunk-2TSADFQX.js.map +1 -0
- package/dist/chunk-3Y5O5EGB.js +3 -0
- package/dist/{chunk-NVJ3ZO3P.js.map → chunk-3Y5O5EGB.js.map} +1 -1
- package/dist/{chunk-6X5BERRF.js → chunk-6RKHCJUU.js} +2 -2
- package/dist/{chunk-6X5BERRF.js.map → chunk-6RKHCJUU.js.map} +1 -1
- package/dist/{chunk-MUYLRTSR.js → chunk-7EBKWATZ.js} +9 -5
- package/dist/chunk-7EBKWATZ.js.map +1 -0
- package/dist/{chunk-BTCZU2DJ.js → chunk-7EMUOH77.js} +4 -4
- package/dist/{chunk-BTCZU2DJ.js.map → chunk-7EMUOH77.js.map} +1 -1
- package/dist/{chunk-QSQ2BSGG.js → chunk-7M6FHFHP.js} +4 -4
- package/dist/{chunk-QSQ2BSGG.js.map → chunk-7M6FHFHP.js.map} +1 -1
- package/dist/{chunk-IWTFVGMK.js → chunk-AKDL2ZX7.js} +2 -2
- package/dist/{chunk-IWTFVGMK.js.map → chunk-AKDL2ZX7.js.map} +1 -1
- package/dist/{chunk-2YLGY3R2.js → chunk-BCMR7Y4U.js} +7 -7
- package/dist/chunk-BCMR7Y4U.js.map +1 -0
- package/dist/{chunk-34LDT5EG.js → chunk-BEHVGFIM.js} +85 -34
- package/dist/chunk-BEHVGFIM.js.map +1 -0
- package/dist/{chunk-3YV6X6VQ.js → chunk-DV2CXHOY.js} +5 -5
- package/dist/chunk-DV2CXHOY.js.map +1 -0
- package/dist/chunk-HFJXYY4E.js +3 -0
- package/dist/chunk-HFJXYY4E.js.map +1 -0
- package/dist/{chunk-VB7VNXR7.js → chunk-HXSK5P2X.js} +11 -5
- package/dist/chunk-HXSK5P2X.js.map +1 -0
- package/dist/{chunk-N4NLAIEN.js → chunk-L3MX5MTA.js} +4 -3
- package/dist/chunk-L3MX5MTA.js.map +1 -0
- package/dist/{chunk-5BOUGXZO.js → chunk-L46TQXCV.js} +22 -6
- package/dist/chunk-L46TQXCV.js.map +1 -0
- package/dist/{chunk-SF5GQHUU.js → chunk-N63S5NEG.js} +10 -3
- package/dist/chunk-N63S5NEG.js.map +1 -0
- package/dist/{chunk-C3ZT7FNO.js → chunk-RAZWRNAJ.js} +5 -5
- package/dist/chunk-RAZWRNAJ.js.map +1 -0
- package/dist/chunk-TKSSRS5U.js +39 -0
- package/dist/chunk-TKSSRS5U.js.map +1 -0
- package/dist/{chunk-O3QJFRXS.js → chunk-U7DKCIWT.js} +37 -19
- package/dist/chunk-U7DKCIWT.js.map +1 -0
- package/dist/chunk-UNORA7EM.js +103 -0
- package/dist/chunk-UNORA7EM.js.map +1 -0
- package/dist/{chunk-NQORJ53O.js → chunk-XZZWIJ4G.js} +4 -4
- package/dist/{chunk-NQORJ53O.js.map → chunk-XZZWIJ4G.js.map} +1 -1
- package/dist/{chunk-XDI4TJHA.js → chunk-ZETQCNEF.js} +49 -5
- package/dist/chunk-ZETQCNEF.js.map +1 -0
- package/dist/container-factory.d.ts +1 -1
- package/dist/container-factory.js +7 -7
- package/dist/context.d.ts +15 -2
- package/dist/context.js +1 -1
- package/dist/error-mapper.d.ts +1 -1
- package/dist/evaluator.d.ts +1 -1
- package/dist/flow.d.ts +3 -3
- package/dist/flow.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +18 -15
- package/dist/linter.d.ts +1 -1
- package/dist/logger.d.ts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/nodes/batch-gather.d.ts +1 -1
- package/dist/nodes/batch-scatter.d.ts +1 -1
- package/dist/nodes/sleep.d.ts +1 -1
- package/dist/nodes/subflow.d.ts +1 -1
- package/dist/nodes/subflow.js +4 -4
- package/dist/nodes/wait.d.ts +1 -1
- package/dist/nodes/webhook.d.ts +1 -1
- package/dist/runtime/adapter.d.ts +3 -1
- package/dist/runtime/adapter.js +12 -12
- package/dist/runtime/execution-context.d.ts +1 -1
- package/dist/runtime/execution-context.js +3 -3
- package/dist/runtime/executors.d.ts +1 -1
- package/dist/runtime/index.d.ts +2 -1
- package/dist/runtime/index.js +14 -13
- package/dist/runtime/node-executor-factory.d.ts +1 -1
- package/dist/runtime/orchestrator.d.ts +1 -1
- package/dist/runtime/orchestrator.js +5 -5
- package/dist/runtime/orchestrators/replay.d.ts +45 -0
- package/dist/runtime/orchestrators/replay.js +3 -0
- package/dist/runtime/orchestrators/replay.js.map +1 -0
- package/dist/runtime/orchestrators/step-by-step.d.ts +1 -1
- package/dist/runtime/orchestrators/step-by-step.js +2 -2
- package/dist/runtime/orchestrators/utils.d.ts +1 -1
- package/dist/runtime/orchestrators/utils.js +1 -1
- package/dist/runtime/runtime.d.ts +1 -1
- package/dist/runtime/runtime.js +11 -11
- package/dist/runtime/scheduler.d.ts +1 -1
- package/dist/runtime/state.d.ts +1 -1
- package/dist/runtime/state.js +2 -2
- package/dist/runtime/traverser.d.ts +1 -1
- package/dist/runtime/types.d.ts +1 -1
- package/dist/runtime/workflow-logic-handler.d.ts +2 -2
- package/dist/runtime/workflow-logic-handler.js +2 -2
- package/dist/sanitizer.d.ts +1 -2
- package/dist/sanitizer.js +1 -1
- package/dist/serializer.d.ts +1 -1
- package/dist/serializer.js +1 -1
- package/dist/testing/event-logger.d.ts +1 -1
- package/dist/testing/event-logger.js +1 -1
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +20 -17
- package/dist/testing/run-with-trace.d.ts +1 -1
- package/dist/testing/run-with-trace.js +16 -15
- package/dist/testing/stepper.d.ts +1 -1
- package/dist/testing/stepper.js +6 -6
- package/dist/{types-Cv5JcMwI.d.ts → types-CKhffqyb.d.ts} +49 -6
- package/dist/types.d.ts +1 -1
- package/package.json +2 -2
- package/dist/chunk-2YLGY3R2.js.map +0 -1
- package/dist/chunk-34LDT5EG.js.map +0 -1
- package/dist/chunk-3YV6X6VQ.js.map +0 -1
- package/dist/chunk-5BOUGXZO.js.map +0 -1
- package/dist/chunk-C3ZT7FNO.js.map +0 -1
- package/dist/chunk-HLN72CCU.js +0 -43
- package/dist/chunk-HLN72CCU.js.map +0 -1
- package/dist/chunk-MUYLRTSR.js.map +0 -1
- package/dist/chunk-N4NLAIEN.js.map +0 -1
- package/dist/chunk-NVJ3ZO3P.js +0 -3
- package/dist/chunk-O3QJFRXS.js.map +0 -1
- package/dist/chunk-SF5GQHUU.js.map +0 -1
- package/dist/chunk-VB7VNXR7.js.map +0 -1
- package/dist/chunk-XDI4TJHA.js.map +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// src/sanitizer.ts
|
|
2
|
+
function sanitizeBlueprint(raw) {
|
|
3
|
+
let nodesArray = [];
|
|
4
|
+
if (Array.isArray(raw.nodes)) {
|
|
5
|
+
nodesArray = raw.nodes;
|
|
6
|
+
} else if (typeof raw.nodes === "object" && raw.nodes !== null) {
|
|
7
|
+
nodesArray = Object.values(raw.nodes);
|
|
8
|
+
}
|
|
9
|
+
const nodes = nodesArray.map((node) => ({
|
|
10
|
+
id: node.id,
|
|
11
|
+
uses: node.uses,
|
|
12
|
+
params: node.params,
|
|
13
|
+
inputs: node.inputs,
|
|
14
|
+
config: node.config
|
|
15
|
+
}));
|
|
16
|
+
let edgesArray = [];
|
|
17
|
+
if (Array.isArray(raw.edges)) {
|
|
18
|
+
edgesArray = raw.edges;
|
|
19
|
+
} else if (typeof raw.edges === "object" && raw.edges !== null) {
|
|
20
|
+
edgesArray = Object.values(raw.edges);
|
|
21
|
+
}
|
|
22
|
+
const edges = edgesArray.map((edge) => ({
|
|
23
|
+
source: edge.source,
|
|
24
|
+
target: edge.target,
|
|
25
|
+
action: edge.action,
|
|
26
|
+
condition: edge.condition,
|
|
27
|
+
transform: edge.transform
|
|
28
|
+
}));
|
|
29
|
+
return {
|
|
30
|
+
id: raw.id,
|
|
31
|
+
nodes,
|
|
32
|
+
edges,
|
|
33
|
+
metadata: raw.metadata
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { sanitizeBlueprint };
|
|
38
|
+
//# sourceMappingURL=chunk-TKSSRS5U.js.map
|
|
39
|
+
//# sourceMappingURL=chunk-TKSSRS5U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sanitizer.ts"],"names":[],"mappings":";AAOO,SAAS,kBAAkB,GAAA,EAA6B;AAC9D,EAAA,IAAI,aAAoB,EAAC;AACzB,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AAC7B,IAAA,UAAA,GAAa,GAAA,CAAI,KAAA;AAAA,EAClB,WAAW,OAAO,GAAA,CAAI,UAAU,QAAA,IAAY,GAAA,CAAI,UAAU,IAAA,EAAM;AAC/D,IAAA,UAAA,GAAa,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,EACrC;AAEA,EAAA,MAAM,KAAA,GAA0B,UAAA,CAAW,GAAA,CAAI,CAAC,IAAA,MAAe;AAAA,IAC9D,IAAI,IAAA,CAAK,EAAA;AAAA,IACT,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,IAAA,CAAK;AAAA,GACd,CAAE,CAAA;AAEF,EAAA,IAAI,aAAoB,EAAC;AACzB,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AAC7B,IAAA,UAAA,GAAa,GAAA,CAAI,KAAA;AAAA,EAClB,WAAW,OAAO,GAAA,CAAI,UAAU,QAAA,IAAY,GAAA,CAAI,UAAU,IAAA,EAAM;AAC/D,IAAA,UAAA,GAAa,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,EACrC;AAEA,EAAA,MAAM,KAAA,GAA0B,UAAA,CAAW,GAAA,CAAI,CAAC,IAAA,MAAe;AAAA,IAC9D,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,WAAW,IAAA,CAAK;AAAA,GACjB,CAAE,CAAA;AAEF,EAAA,OAAO;AAAA,IACN,IAAI,GAAA,CAAI,EAAA;AAAA,IACR,KAAA;AAAA,IACA,KAAA;AAAA,IACA,UAAU,GAAA,CAAI;AAAA,GACf;AACD","file":"chunk-TKSSRS5U.js","sourcesContent":["import type { EdgeDefinition, NodeDefinition, WorkflowBlueprint } from './types'\n\n/**\n * Sanitizes a raw workflow blueprint by removing extra properties\n * added by UI tools (e.g., position, style) and keeping only the\n * properties defined in NodeDefinition and EdgeDefinition.\n */\nexport function sanitizeBlueprint(raw: any): WorkflowBlueprint {\n\tlet nodesArray: any[] = []\n\tif (Array.isArray(raw.nodes)) {\n\t\tnodesArray = raw.nodes\n\t} else if (typeof raw.nodes === 'object' && raw.nodes !== null) {\n\t\tnodesArray = Object.values(raw.nodes)\n\t}\n\n\tconst nodes: NodeDefinition[] = nodesArray.map((node: any) => ({\n\t\tid: node.id,\n\t\tuses: node.uses,\n\t\tparams: node.params,\n\t\tinputs: node.inputs,\n\t\tconfig: node.config,\n\t}))\n\n\tlet edgesArray: any[] = []\n\tif (Array.isArray(raw.edges)) {\n\t\tedgesArray = raw.edges\n\t} else if (typeof raw.edges === 'object' && raw.edges !== null) {\n\t\tedgesArray = Object.values(raw.edges)\n\t}\n\n\tconst edges: EdgeDefinition[] = edgesArray.map((edge: any) => ({\n\t\tsource: edge.source,\n\t\ttarget: edge.target,\n\t\taction: edge.action,\n\t\tcondition: edge.condition,\n\t\ttransform: edge.transform,\n\t}))\n\n\treturn {\n\t\tid: raw.id,\n\t\tnodes,\n\t\tedges,\n\t\tmetadata: raw.metadata,\n\t}\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { FlowRuntime } from './chunk-
|
|
1
|
+
import { FlowRuntime } from './chunk-BEHVGFIM.js';
|
|
2
2
|
import { analyzeBlueprint } from './chunk-ZLW4QOTS.js';
|
|
3
|
+
import { WorkflowState } from './chunk-L46TQXCV.js';
|
|
3
4
|
import { ConsoleLogger } from './chunk-4PELJWF7.js';
|
|
4
|
-
import { JsonSerializer } from './chunk-
|
|
5
|
-
import { TrackedAsyncContext } from './chunk-
|
|
5
|
+
import { JsonSerializer } from './chunk-6RKHCJUU.js';
|
|
6
|
+
import { TrackedAsyncContext } from './chunk-ZETQCNEF.js';
|
|
6
7
|
|
|
7
8
|
// src/runtime/adapter.ts
|
|
8
9
|
var BaseDistributedAdapter = class {
|
|
@@ -10,6 +11,7 @@ var BaseDistributedAdapter = class {
|
|
|
10
11
|
store;
|
|
11
12
|
serializer;
|
|
12
13
|
logger;
|
|
14
|
+
eventBus;
|
|
13
15
|
constructor(options) {
|
|
14
16
|
const runtimeOptions = {
|
|
15
17
|
...options.runtimeOptions,
|
|
@@ -22,6 +24,7 @@ var BaseDistributedAdapter = class {
|
|
|
22
24
|
this.store = options.coordinationStore;
|
|
23
25
|
this.serializer = options.runtimeOptions.serializer || new JsonSerializer();
|
|
24
26
|
this.logger = options.runtimeOptions.logger || new ConsoleLogger();
|
|
27
|
+
this.eventBus = options.eventBus;
|
|
25
28
|
this.logger.info("[Adapter] BaseDistributedAdapter initialized.");
|
|
26
29
|
}
|
|
27
30
|
/**
|
|
@@ -42,6 +45,7 @@ var BaseDistributedAdapter = class {
|
|
|
42
45
|
*/
|
|
43
46
|
async handleJob(job) {
|
|
44
47
|
const { runId, blueprintId, nodeId } = job;
|
|
48
|
+
const startTime = Date.now();
|
|
45
49
|
await this.onJobStart(runId, blueprintId, nodeId);
|
|
46
50
|
const blueprint = this.runtime.options.blueprints?.[blueprintId];
|
|
47
51
|
if (!blueprint) {
|
|
@@ -75,21 +79,16 @@ var BaseDistributedAdapter = class {
|
|
|
75
79
|
this.logger.debug(`[Adapter] Extended TTLs for run ${runId}, node ${nodeId}`);
|
|
76
80
|
}, 18e5);
|
|
77
81
|
try {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
},
|
|
82
|
-
addError: (nodeId2, error) => {
|
|
83
|
-
this.logger.error(`[Adapter] Error in node ${nodeId2}:`, error);
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
const result = await this.runtime.executeNode(blueprint, nodeId, workerState);
|
|
82
|
+
const contextData = await context.toJSON();
|
|
83
|
+
const state = new WorkflowState(contextData, context);
|
|
84
|
+
const result = await this.runtime.executeNode(blueprint, nodeId, state);
|
|
87
85
|
await context.set(`_outputs.${nodeId}`, result.output);
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
const stateContext = state.getContext();
|
|
87
|
+
if (stateContext instanceof TrackedAsyncContext) {
|
|
88
|
+
const deltas = stateContext.getDeltas();
|
|
90
89
|
if (deltas.length > 0) {
|
|
91
|
-
await
|
|
92
|
-
|
|
90
|
+
await stateContext.patch(deltas);
|
|
91
|
+
stateContext.clearDeltas();
|
|
93
92
|
}
|
|
94
93
|
}
|
|
95
94
|
const analysis = analyzeBlueprint(blueprint);
|
|
@@ -132,20 +131,39 @@ var BaseDistributedAdapter = class {
|
|
|
132
131
|
return;
|
|
133
132
|
}
|
|
134
133
|
for (const { node: nextNodeDef, edge } of nextNodes) {
|
|
135
|
-
await this.runtime.applyEdgeTransform(edge, result, nextNodeDef, context);
|
|
134
|
+
await this.runtime.applyEdgeTransform(edge, result, nextNodeDef, context, void 0, runId);
|
|
136
135
|
const isReady = await this.isReadyForFanIn(runId, blueprint, nextNodeDef.id);
|
|
137
136
|
if (isReady) {
|
|
138
137
|
this.logger.info(`[Adapter] Node '${nextNodeDef.id}' is ready. Enqueuing job.`);
|
|
139
138
|
await this.enqueueJob({ runId, blueprintId, nodeId: nextNodeDef.id });
|
|
139
|
+
if (this.eventBus) {
|
|
140
|
+
await this.eventBus.emit({
|
|
141
|
+
type: "job:enqueued",
|
|
142
|
+
payload: { runId, blueprintId, nodeId: nextNodeDef.id }
|
|
143
|
+
});
|
|
144
|
+
}
|
|
140
145
|
} else {
|
|
141
146
|
this.logger.info(`[Adapter] Node '${nextNodeDef.id}' is waiting for other predecessors to complete.`);
|
|
142
147
|
}
|
|
143
148
|
}
|
|
149
|
+
const duration = Date.now() - startTime;
|
|
150
|
+
if (this.eventBus) {
|
|
151
|
+
await this.eventBus.emit({
|
|
152
|
+
type: "job:processed",
|
|
153
|
+
payload: { runId, blueprintId, nodeId, duration, success: true }
|
|
154
|
+
});
|
|
155
|
+
}
|
|
144
156
|
} catch (error) {
|
|
145
157
|
const reason = error.message || "Unknown execution error";
|
|
146
158
|
this.logger.error(`[Adapter] FATAL: Job for node '${nodeId}' failed for Run ID '${runId}': ${reason}`);
|
|
147
159
|
await this.publishFinalResult(runId, { status: "failed", reason });
|
|
148
160
|
await this.writePoisonPillForSuccessors(runId, blueprint, nodeId);
|
|
161
|
+
if (this.eventBus) {
|
|
162
|
+
await this.eventBus.emit({
|
|
163
|
+
type: "job:failed",
|
|
164
|
+
payload: { runId, blueprintId, nodeId, error }
|
|
165
|
+
});
|
|
166
|
+
}
|
|
149
167
|
} finally {
|
|
150
168
|
clearInterval(heartbeatInterval);
|
|
151
169
|
}
|
|
@@ -318,5 +336,5 @@ var BaseDistributedAdapter = class {
|
|
|
318
336
|
};
|
|
319
337
|
|
|
320
338
|
export { BaseDistributedAdapter };
|
|
321
|
-
//# sourceMappingURL=chunk-
|
|
322
|
-
//# sourceMappingURL=chunk-
|
|
339
|
+
//# sourceMappingURL=chunk-U7DKCIWT.js.map
|
|
340
|
+
//# sourceMappingURL=chunk-U7DKCIWT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/adapter.ts"],"names":["blueprintKey"],"mappings":"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","file":"chunk-U7DKCIWT.js","sourcesContent":["import { analyzeBlueprint } from '../analysis'\nimport { TrackedAsyncContext } from '../context'\nimport { ConsoleLogger } from '../logger'\nimport { JsonSerializer } from '../serializer'\nimport type {\n\tIAsyncContext,\n\tIEventBus,\n\tILogger,\n\tISerializer,\n\tNodeResult,\n\tRuntimeOptions,\n\tWorkflowBlueprint,\n\tWorkflowResult,\n} from '../types'\nimport { FlowRuntime } from './runtime'\nimport { WorkflowState } from './state'\n\n/**\n * Defines the contract for an atomic, distributed key-value store required by\n * the adapter for coordination tasks like fan-in joins and locking.\n */\nexport interface ICoordinationStore {\n\t/** Atomically increments a key and returns the new value. Ideal for 'all' joins. */\n\tincrement: (key: string, ttlSeconds: number) => Promise<number>\n\t/** Sets a key only if it does not already exist. Ideal for 'any' joins (locking). */\n\tsetIfNotExist: (key: string, value: string, ttlSeconds: number) => Promise<boolean>\n\t/** Extends the TTL of an existing key. Used for heartbeat mechanism in long-running jobs. */\n\textendTTL: (key: string, ttlSeconds: number) => Promise<boolean>\n\t/** Deletes a key. Used for cleanup. */\n\tdelete: (key: string) => Promise<void>\n\t/** Gets the value of a key. */\n\tget: (key: string) => Promise<string | undefined>\n}\n\n/** Configuration options for constructing a BaseDistributedAdapter. */\nexport interface AdapterOptions {\n\truntimeOptions: RuntimeOptions<any>\n\tcoordinationStore: ICoordinationStore\n\teventBus?: IEventBus\n}\n\n/** The data payload expected for a job in the queue. */\nexport interface JobPayload {\n\trunId: string\n\tblueprintId: string\n\tnodeId: string\n}\n\n/**\n * The base class for all distributed adapters. It handles the technology-agnostic\n * orchestration logic and leaves queue-specific implementation to subclasses.\n */\nexport abstract class BaseDistributedAdapter {\n\tprotected readonly runtime: FlowRuntime<any, any>\n\tprotected readonly store: ICoordinationStore\n\tprotected readonly serializer: ISerializer\n\tprotected readonly logger: ILogger\n\tprotected readonly eventBus?: IEventBus\n\n\tconstructor(options: AdapterOptions) {\n\t\tconst runtimeOptions = {\n\t\t\t...options.runtimeOptions,\n\t\t\tdependencies: {\n\t\t\t\t...options.runtimeOptions.dependencies,\n\t\t\t\tadapter: this,\n\t\t\t} as any,\n\t\t}\n\t\tthis.runtime = new FlowRuntime(runtimeOptions)\n\t\tthis.store = options.coordinationStore\n\t\tthis.serializer = options.runtimeOptions.serializer || new JsonSerializer()\n\t\tthis.logger = options.runtimeOptions.logger || new ConsoleLogger()\n\t\tthis.eventBus = options.eventBus\n\t\tthis.logger.info('[Adapter] BaseDistributedAdapter initialized.')\n\t}\n\n\t/**\n\t * Starts the worker, which begins listening for and processing jobs from the queue.\n\t */\n\tpublic start(): void {\n\t\tthis.logger.info('[Adapter] Starting worker...')\n\t\tthis.processJobs(this.handleJob.bind(this))\n\t}\n\n\t/**\n\t * Creates a technology-specific distributed context for a given workflow run.\n\t * @param runId The unique ID for the workflow execution.\n\t */\n\tprotected abstract createContext(runId: string): IAsyncContext<Record<string, any>>\n\t/**\n\t * Sets up the listener for the message queue. The implementation should call the\n\t * provided `handler` function for each new job received.\n\t * @param handler The core logic to execute for each job.\n\t */\n\tprotected abstract processJobs(handler: (job: JobPayload) => Promise<void>): void\n\n\t/**\n\t * Enqueues a new job onto the message queue.\n\t * @param job The payload for the job to be enqueued.\n\t */\n\tprotected abstract enqueueJob(job: JobPayload): Promise<void>\n\n\t/**\n\t * Publishes the final result of a completed or failed workflow run.\n\t * @param runId The unique ID of the workflow run.\n\t * @param result The final status and payload of the workflow.\n\t */\n\tprotected abstract publishFinalResult(\n\t\trunId: string,\n\t\tresult: {\n\t\t\tstatus: 'completed' | 'failed'\n\t\t\tpayload?: WorkflowResult\n\t\t\treason?: string\n\t\t},\n\t): Promise<void>\n\n\t/**\n\t * Registers a webhook endpoint for a specific node in a workflow run.\n\t * @param runId The unique ID of the workflow run.\n\t * @param nodeId The ID of the node that will wait for the webhook.\n\t * @returns The URL and event name for the webhook.\n\t */\n\tpublic abstract registerWebhookEndpoint(runId: string, nodeId: string): Promise<{ url: string; event: string }>\n\n\t/**\n\t * Hook called at the start of job processing. Subclasses can override this\n\t * to perform additional setup (e.g., timestamp tracking for reconciliation).\n\t */\n\tprotected async onJobStart(_runId: string, _blueprintId: string, _nodeId: string): Promise<void> {\n\t\t// default implementation does nothing\n\t}\n\n\t/**\n\t * The main handler for processing a single job from the queue.\n\t */\n\tprotected async handleJob(job: JobPayload): Promise<void> {\n\t\tconst { runId, blueprintId, nodeId } = job\n\t\tconst startTime = Date.now()\n\n\t\tawait this.onJobStart(runId, blueprintId, nodeId)\n\n\t\tconst blueprint = this.runtime.options.blueprints?.[blueprintId]\n\t\tif (!blueprint) {\n\t\t\tconst reason = `Blueprint with ID '${blueprintId}' not found in the worker's runtime registry.`\n\t\t\tthis.logger.error(`[Adapter] FATAL: ${reason}`)\n\t\t\tawait this.publishFinalResult(runId, { status: 'failed', reason })\n\t\t\treturn\n\t\t}\n\n\t\tconst context = this.createContext(runId)\n\n\t\tconst storedVersion = await context.get('blueprintVersion' as any)\n\t\tconst currentVersion = blueprint.metadata?.version || null\n\t\tif (storedVersion !== currentVersion) {\n\t\t\tconst reason = `Blueprint version mismatch: stored version '${storedVersion}', current version '${currentVersion}'. Rejecting job to prevent state corruption.`\n\t\t\tthis.logger.warn(`[Adapter] Version mismatch for run ${runId}, node ${nodeId}: ${reason}`)\n\t\t\treturn\n\t\t}\n\n\t\t// persist the blueprintId and version for the reconcile method to find later\n\t\tconst hasBlueprintId = await context.has('blueprintId' as any)\n\t\tif (!hasBlueprintId) {\n\t\t\tawait context.set('blueprintId' as any, blueprintId)\n\t\t\tawait context.set('blueprintVersion' as any, blueprint.metadata?.version || null)\n\t\t\t// also store in coordination store as fallback\n\t\t\tconst blueprintKey = `flowcraft:blueprint:${runId}`\n\t\t\tawait this.store.setIfNotExist(blueprintKey, blueprintId, 3600)\n\t\t}\n\n\t\t// heartbeat to extend TTLs of coordination keys for long-running jobs\n\t\tconst joinLockKey = `flowcraft:joinlock:${runId}:${nodeId}`\n\t\tconst fanInKey = `flowcraft:fanin:${runId}:${nodeId}`\n\t\tconst blueprintKey = `flowcraft:blueprint:${runId}`\n\t\tconst heartbeatInterval = setInterval(async () => {\n\t\t\tawait this.store.extendTTL(joinLockKey, 3600)\n\t\t\tawait this.store.extendTTL(fanInKey, 3600)\n\t\t\tawait this.store.extendTTL(blueprintKey, 3600)\n\t\t\tthis.logger.debug(`[Adapter] Extended TTLs for run ${runId}, node ${nodeId}`)\n\t\t}, 1800000) // 30 minutes\n\n\t\ttry {\n\t\t\tconst contextData = await context.toJSON()\n\t\t\tconst state = new WorkflowState(contextData, context)\n\n\t\t\tconst result: NodeResult<any, any> = await this.runtime.executeNode(blueprint, nodeId, state)\n\t\t\tawait context.set(`_outputs.${nodeId}` as any, result.output)\n\n\t\t\tconst stateContext = state.getContext()\n\t\t\tif (stateContext instanceof TrackedAsyncContext) {\n\t\t\t\tconst deltas = stateContext.getDeltas()\n\t\t\t\tif (deltas.length > 0) {\n\t\t\t\t\tawait stateContext.patch(deltas)\n\t\t\t\t\tstateContext.clearDeltas()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst analysis = analyzeBlueprint(blueprint)\n\t\t\tconst isTerminalNode = analysis.terminalNodeIds.includes(nodeId)\n\n\t\t\tif (isTerminalNode) {\n\t\t\t\tconst allContextKeys = Object.keys(await context.toJSON())\n\t\t\t\tconst completedNodes = new Set<string>()\n\t\t\t\tfor (const key of allContextKeys) {\n\t\t\t\t\tif (key.startsWith('_outputs.')) {\n\t\t\t\t\t\tcompletedNodes.add(key.substring('_outputs.'.length))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst allTerminalNodesCompleted = analysis.terminalNodeIds.every((terminalId) => completedNodes.has(terminalId))\n\n\t\t\t\tif (allTerminalNodesCompleted) {\n\t\t\t\t\tthis.logger.info(`[Adapter] All terminal nodes completed for Run ID: ${runId}. Declaring workflow complete.`)\n\t\t\t\t\tconst finalContext = await context.toJSON()\n\t\t\t\t\tconst finalResult: WorkflowResult = {\n\t\t\t\t\t\tcontext: finalContext,\n\t\t\t\t\t\tserializedContext: this.serializer.serialize(finalContext),\n\t\t\t\t\t\tstatus: 'completed',\n\t\t\t\t\t}\n\t\t\t\t\tawait this.publishFinalResult(runId, {\n\t\t\t\t\t\tstatus: 'completed',\n\t\t\t\t\t\tpayload: finalResult,\n\t\t\t\t\t})\n\t\t\t\t\tclearInterval(heartbeatInterval)\n\t\t\t\t\treturn\n\t\t\t\t} else {\n\t\t\t\t\tthis.logger.info(\n\t\t\t\t\t\t`[Adapter] Terminal node '${nodeId}' completed for Run ID '${runId}', but other terminal nodes are still running.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst nextNodes = await this.runtime.determineNextNodes(blueprint, nodeId, result, context, runId)\n\n\t\t\t// stop if a branch terminates but it wasn't a terminal node\n\t\t\tif (nextNodes.length === 0 && !isTerminalNode) {\n\t\t\t\tthis.logger.info(\n\t\t\t\t\t`[Adapter] Non-terminal node '${nodeId}' reached end of branch for Run ID '${runId}'. This branch will now terminate.`,\n\t\t\t\t)\n\t\t\t\tclearInterval(heartbeatInterval)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tfor (const { node: nextNodeDef, edge } of nextNodes) {\n\t\t\t\tawait this.runtime.applyEdgeTransform(edge, result, nextNodeDef, context, undefined, runId)\n\t\t\t\tconst isReady = await this.isReadyForFanIn(runId, blueprint, nextNodeDef.id)\n\t\t\t\tif (isReady) {\n\t\t\t\t\tthis.logger.info(`[Adapter] Node '${nextNodeDef.id}' is ready. Enqueuing job.`)\n\t\t\t\t\tawait this.enqueueJob({ runId, blueprintId, nodeId: nextNodeDef.id })\n\t\t\t\t\tif (this.eventBus) {\n\t\t\t\t\t\tawait this.eventBus.emit({\n\t\t\t\t\t\t\ttype: 'job:enqueued',\n\t\t\t\t\t\t\tpayload: { runId, blueprintId, nodeId: nextNodeDef.id },\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.logger.info(`[Adapter] Node '${nextNodeDef.id}' is waiting for other predecessors to complete.`)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst duration = Date.now() - startTime\n\t\t\tif (this.eventBus) {\n\t\t\t\tawait this.eventBus.emit({\n\t\t\t\t\ttype: 'job:processed',\n\t\t\t\t\tpayload: { runId, blueprintId, nodeId, duration, success: true },\n\t\t\t\t})\n\t\t\t}\n\t\t} catch (error: any) {\n\t\t\tconst reason = error.message || 'Unknown execution error'\n\t\t\tthis.logger.error(`[Adapter] FATAL: Job for node '${nodeId}' failed for Run ID '${runId}': ${reason}`)\n\t\t\tawait this.publishFinalResult(runId, { status: 'failed', reason })\n\t\t\tawait this.writePoisonPillForSuccessors(runId, blueprint, nodeId)\n\n\t\t\tif (this.eventBus) {\n\t\t\t\tawait this.eventBus.emit({\n\t\t\t\t\ttype: 'job:failed',\n\t\t\t\t\tpayload: { runId, blueprintId, nodeId, error },\n\t\t\t\t})\n\t\t\t}\n\t\t} finally {\n\t\t\tclearInterval(heartbeatInterval)\n\t\t}\n\t}\n\n\t/**\n\t * Encapsulates the fan-in join logic using the coordination store.\n\t */\n\tprotected async isReadyForFanIn(runId: string, blueprint: WorkflowBlueprint, targetNodeId: string): Promise<boolean> {\n\t\tconst targetNode = blueprint.nodes.find((n) => n.id === targetNodeId)\n\t\tif (!targetNode) {\n\t\t\tthrow new Error(`Node '${targetNodeId}' not found in blueprint`)\n\t\t}\n\t\tconst joinStrategy = targetNode.config?.joinStrategy || 'all'\n\t\tconst predecessors = blueprint.edges.filter((e) => e.target === targetNodeId)\n\n\t\tif (predecessors.length <= 1) {\n\t\t\treturn true\n\t\t}\n\n\t\tconst poisonKey = `flowcraft:fanin:poison:${runId}:${targetNodeId}`\n\t\tconst isPoisoned = await this.store.get(poisonKey)\n\t\tif (isPoisoned) {\n\t\t\tthis.logger.info(`[Adapter] Node '${targetNodeId}' is poisoned due to failed predecessor. Failing immediately.`)\n\t\t\tthrow new Error(`Node '${targetNodeId}' failed due to poisoned predecessor in run '${runId}'`)\n\t\t}\n\n\t\tif (joinStrategy === 'any') {\n\t\t\tconst lockKey = `flowcraft:joinlock:${runId}:${targetNodeId}`\n\t\t\tconst isLocked = await this.store.setIfNotExist(lockKey, 'locked', 3600)\n\t\t\tif (!isLocked) {\n\t\t\t\t// check if cancelled\n\t\t\t\tconst cancelKey = `flowcraft:fanin:cancel:${runId}:${targetNodeId}`\n\t\t\t\tconst isCancelled = !(await this.store.setIfNotExist(cancelKey, 'cancelled', 3600))\n\t\t\t\tif (isCancelled) {\n\t\t\t\t\tthis.logger.info(\n\t\t\t\t\t\t`[Adapter] Node '${targetNodeId}' is cancelled due to failed predecessor. Failing immediately.`,\n\t\t\t\t\t)\n\t\t\t\t\tthrow new Error(`Node '${targetNodeId}' failed due to cancelled predecessor in run '${runId}'`)\n\t\t\t\t}\n\t\t\t\treturn false // already locked by another predecessor\n\t\t\t}\n\t\t\treturn true\n\t\t} else {\n\t\t\tconst fanInKey = `flowcraft:fanin:${runId}:${targetNodeId}`\n\t\t\tconst readyCount = await this.store.increment(fanInKey, 3600)\n\t\t\tif (readyCount >= predecessors.length) {\n\t\t\t\tawait this.store.delete(fanInKey)\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * Reconciles the state of a workflow run. It inspects the persisted\n\t * context to find completed nodes, determines the next set of executable\n\t * nodes (the frontier), and enqueues jobs for them if they aren't\n\t * already running. This is the core of the resume functionality.\n\t *\n\t * @param runId The unique ID of the workflow execution to reconcile.\n\t * @returns The set of node IDs that were enqueued for execution.\n\t */\n\tpublic async reconcile(runId: string): Promise<Set<string>> {\n\t\tconst context = this.createContext(runId)\n\t\tlet blueprintId = (await context.get('blueprintId' as any)) as string | undefined\n\n\t\tif (!blueprintId) {\n\t\t\t// fallback to coordination store\n\t\t\tconst blueprintKey = `flowcraft:blueprint:${runId}`\n\t\t\tblueprintId = await this.store.get(blueprintKey)\n\t\t\tif (blueprintId) {\n\t\t\t\t// set it back in context for future use\n\t\t\t\tawait context.set('blueprintId' as any, blueprintId)\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Cannot reconcile runId '${runId}': blueprintId not found in context or coordination store.`)\n\t\t\t}\n\t\t}\n\t\tconst blueprint = this.runtime.options.blueprints?.[blueprintId]\n\t\tif (blueprint && !(await context.has('blueprintVersion' as any))) {\n\t\t\tawait context.set('blueprintVersion' as any, blueprint.metadata?.version || null)\n\t\t}\n\t\tif (!blueprint) {\n\t\t\tthrow new Error(`Cannot reconcile runId '${runId}': Blueprint with ID '${blueprintId}' not found.`)\n\t\t}\n\n\t\tconst state = await context.toJSON()\n\t\tconst completedNodes = new Set<string>()\n\t\tfor (const key of Object.keys(state)) {\n\t\t\tif (key.startsWith('_outputs.')) {\n\t\t\t\tcompletedNodes.add(key.substring('_outputs.'.length))\n\t\t\t}\n\t\t}\n\n\t\tconst frontier = this.calculateResumedFrontier(blueprint, completedNodes)\n\n\t\tconst enqueuedNodes = new Set<string>()\n\t\tfor (const nodeId of frontier) {\n\t\t\tconst nodeDef = blueprint.nodes.find((n) => n.id === nodeId)\n\t\t\tconst joinStrategy = nodeDef?.config?.joinStrategy || 'all'\n\n\t\t\tconst poisonKey = `flowcraft:fanin:poison:${runId}:${nodeId}`\n\t\t\tconst isPoisoned = await this.store.get(poisonKey)\n\t\t\tif (isPoisoned) {\n\t\t\t\tthis.logger.info(`[Adapter] Reconciling: Node '${nodeId}' is poisoned, skipping.`, { runId })\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet shouldEnqueue = false\n\n\t\t\tif (joinStrategy === 'any') {\n\t\t\t\t// acquire the permanent join lock\n\t\t\t\tconst lockKey = `flowcraft:joinlock:${runId}:${nodeId}`\n\t\t\t\tif (await this.store.setIfNotExist(lockKey, 'locked-by-reconcile', 3600)) {\n\t\t\t\t\tshouldEnqueue = true\n\t\t\t\t} else {\n\t\t\t\t\tthis.logger.info(`[Adapter] Reconciling: Node '${nodeId}' is an 'any' join and is already locked.`, { runId })\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// 'all' joins and single-predecessor nodes use a temporary lock\n\t\t\t\tconst lockKey = `flowcraft:nodelock:${runId}:${nodeId}`\n\t\t\t\tif (await this.store.setIfNotExist(lockKey, 'locked', 120)) {\n\t\t\t\t\tshouldEnqueue = true\n\t\t\t\t} else {\n\t\t\t\t\tthis.logger.info(`[Adapter] Reconciling: Node '${nodeId}' is already locked.`, { runId })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (shouldEnqueue) {\n\t\t\t\tthis.logger.info(`[Adapter] Reconciling: Enqueuing ready job for node '${nodeId}'`, { runId })\n\t\t\t\tawait this.enqueueJob({ runId, blueprintId: blueprint.id, nodeId })\n\t\t\t\tenqueuedNodes.add(nodeId)\n\t\t\t}\n\t\t}\n\n\t\treturn enqueuedNodes\n\t}\n\n\tprivate calculateResumedFrontier(blueprint: WorkflowBlueprint, completedNodes: Set<string>): Set<string> {\n\t\tconst newFrontier = new Set<string>()\n\t\tconst allPredecessors = new Map<string, Set<string>>()\n\t\t// (logic extracted from the GraphTraverser)\n\t\tfor (const node of blueprint.nodes) {\n\t\t\tallPredecessors.set(node.id, new Set())\n\t\t}\n\t\tfor (const edge of blueprint.edges) {\n\t\t\tallPredecessors.get(edge.target)?.add(edge.source)\n\t\t}\n\n\t\tfor (const node of blueprint.nodes) {\n\t\t\tif (completedNodes.has(node.id)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst predecessors = allPredecessors.get(node.id) ?? new Set()\n\t\t\tif (predecessors.size === 0 && !completedNodes.has(node.id)) {\n\t\t\t\tnewFrontier.add(node.id)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst joinStrategy = node.config?.joinStrategy || 'all'\n\t\t\tconst completedPredecessors = [...predecessors].filter((p) => completedNodes.has(p))\n\n\t\t\tconst isReady =\n\t\t\t\tjoinStrategy === 'any' ? completedPredecessors.length > 0 : completedPredecessors.length === predecessors.size\n\n\t\t\tif (isReady) {\n\t\t\t\tnewFrontier.add(node.id)\n\t\t\t}\n\t\t}\n\t\treturn newFrontier\n\t}\n\n\t/**\n\t * Writes a poison pill for 'all' join successors and a cancellation pill for 'any' join successors of a failed node to prevent stalling or ambiguous states.\n\t */\n\tprivate async writePoisonPillForSuccessors(\n\t\trunId: string,\n\t\tblueprint: WorkflowBlueprint,\n\t\tfailedNodeId: string,\n\t): Promise<void> {\n\t\tconst successors = blueprint.edges\n\t\t\t.filter((edge) => edge.source === failedNodeId)\n\t\t\t.map((edge) => edge.target)\n\t\t\t.map((targetId) => blueprint.nodes.find((node) => node.id === targetId))\n\t\t\t.filter((node) => node)\n\n\t\tfor (const successor of successors) {\n\t\t\tif (successor) {\n\t\t\t\tconst joinStrategy = successor.config?.joinStrategy || 'all'\n\t\t\t\tif (joinStrategy === 'all') {\n\t\t\t\t\tconst poisonKey = `flowcraft:fanin:poison:${runId}:${successor.id}`\n\t\t\t\t\tawait this.store.setIfNotExist(poisonKey, 'poisoned', 3600)\n\t\t\t\t\tthis.logger.info(\n\t\t\t\t\t\t`[Adapter] Wrote poison pill for 'all' join node '${successor.id}' due to failed predecessor '${failedNodeId}'`,\n\t\t\t\t\t)\n\t\t\t\t} else if (joinStrategy === 'any') {\n\t\t\t\t\tconst cancelKey = `flowcraft:fanin:cancel:${runId}:${successor.id}`\n\t\t\t\t\tawait this.store.setIfNotExist(cancelKey, 'cancelled', 3600)\n\t\t\t\t\tthis.logger.info(\n\t\t\t\t\t\t`[Adapter] Wrote cancellation pill for 'any' join node '${successor.id}' due to failed predecessor '${failedNodeId}'`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// src/runtime/orchestrators/replay.ts
|
|
2
|
+
var ReplayOrchestrator = class {
|
|
3
|
+
/**
|
|
4
|
+
* Creates a new ReplayOrchestrator with a sequence of recorded workflow events.
|
|
5
|
+
*
|
|
6
|
+
* @param events - Array of FlowcraftEvent objects representing the recorded workflow execution
|
|
7
|
+
*/
|
|
8
|
+
constructor(events) {
|
|
9
|
+
this.events = events;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Replays the recorded workflow events to reconstruct the workflow state.
|
|
13
|
+
*
|
|
14
|
+
* This method filters events for the specific execution, applies each event in sequence
|
|
15
|
+
* to rebuild the context state, and returns the final reconstructed workflow result.
|
|
16
|
+
* Replayed executions always have a "completed" status since they reconstruct the final state.
|
|
17
|
+
*
|
|
18
|
+
* @param context - The execution context containing state and services
|
|
19
|
+
* @param _traverser - Graph traverser (unused in replay mode)
|
|
20
|
+
* @returns Promise resolving to the reconstructed workflow result
|
|
21
|
+
*/
|
|
22
|
+
async run(context, _traverser) {
|
|
23
|
+
const executionEvents = this.events.filter((event) => {
|
|
24
|
+
if ("executionId" in event.payload) {
|
|
25
|
+
return event.payload.executionId === context.executionId;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
});
|
|
29
|
+
const fallbackMap = /* @__PURE__ */ new Map();
|
|
30
|
+
for (const event of executionEvents) {
|
|
31
|
+
await this.applyEvent(event, context, fallbackMap);
|
|
32
|
+
}
|
|
33
|
+
const includeExecutionId = executionEvents.length > 0;
|
|
34
|
+
const result = await context.state.toResult(
|
|
35
|
+
context.services.serializer,
|
|
36
|
+
includeExecutionId ? context.executionId : void 0
|
|
37
|
+
);
|
|
38
|
+
result.status = "completed";
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Applies a single workflow event to reconstruct the execution state.
|
|
43
|
+
*
|
|
44
|
+
* This method handles different event types by updating the workflow state accordingly,
|
|
45
|
+
* including node completions, context changes, errors, fallbacks, and workflow control events.
|
|
46
|
+
*
|
|
47
|
+
* @param event - The workflow event to apply
|
|
48
|
+
* @param context - The execution context to update
|
|
49
|
+
* @param fallbackMap - Map tracking fallback node relationships (fallbackNodeId -> originalNodeId)
|
|
50
|
+
*/
|
|
51
|
+
async applyEvent(event, context, fallbackMap) {
|
|
52
|
+
const { type, payload } = event;
|
|
53
|
+
switch (type) {
|
|
54
|
+
case "node:start":
|
|
55
|
+
break;
|
|
56
|
+
case "node:finish": {
|
|
57
|
+
const originalNodeId = fallbackMap.get(payload.nodeId);
|
|
58
|
+
if (originalNodeId) {
|
|
59
|
+
await context.state.addCompletedNode(originalNodeId, payload.result.output);
|
|
60
|
+
} else {
|
|
61
|
+
await context.state.addCompletedNode(payload.nodeId, payload.result.output);
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case "context:change":
|
|
66
|
+
if (payload.op === "set") {
|
|
67
|
+
await context.state.getContext().set(payload.key, payload.value);
|
|
68
|
+
} else if (payload.op === "delete") {
|
|
69
|
+
await context.state.getContext().delete(payload.key);
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
case "node:error":
|
|
73
|
+
context.state.addError(payload.nodeId, payload.error);
|
|
74
|
+
break;
|
|
75
|
+
case "node:fallback":
|
|
76
|
+
fallbackMap.set(payload.fallback, payload.nodeId);
|
|
77
|
+
context.state.markFallbackExecuted();
|
|
78
|
+
break;
|
|
79
|
+
case "node:retry":
|
|
80
|
+
break;
|
|
81
|
+
case "edge:evaluate":
|
|
82
|
+
break;
|
|
83
|
+
case "workflow:stall":
|
|
84
|
+
case "workflow:pause":
|
|
85
|
+
if ("remainingNodes" in payload) {
|
|
86
|
+
for (let i = 0; i < payload.remainingNodes; i++) {
|
|
87
|
+
await context.state.markAsAwaiting(`node-${i}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
case "batch:start":
|
|
92
|
+
break;
|
|
93
|
+
case "batch:finish":
|
|
94
|
+
for (const _result of payload.results) {
|
|
95
|
+
}
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export { ReplayOrchestrator };
|
|
102
|
+
//# sourceMappingURL=chunk-UNORA7EM.js.map
|
|
103
|
+
//# sourceMappingURL=chunk-UNORA7EM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/orchestrators/replay.ts"],"names":[],"mappings":"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","file":"chunk-UNORA7EM.js","sourcesContent":["import type { FlowcraftEvent, WorkflowResult } from '../../types'\nimport type { ExecutionContext } from '../execution-context'\nimport type { GraphTraverser } from '../traverser'\nimport type { IOrchestrator } from '../types'\n\n/**\n * An orchestrator that replays a pre-recorded sequence of workflow events\n * to reconstruct the workflow state without executing any node logic.\n *\n * This enables time-travel debugging by allowing developers to inspect\n * the exact state of a workflow at any point in its execution history.\n */\nexport class ReplayOrchestrator implements IOrchestrator {\n\t/**\n\t * Creates a new ReplayOrchestrator with a sequence of recorded workflow events.\n\t *\n\t * @param events - Array of FlowcraftEvent objects representing the recorded workflow execution\n\t */\n\tconstructor(private events: FlowcraftEvent[]) {}\n\n\t/**\n\t * Replays the recorded workflow events to reconstruct the workflow state.\n\t *\n\t * This method filters events for the specific execution, applies each event in sequence\n\t * to rebuild the context state, and returns the final reconstructed workflow result.\n\t * Replayed executions always have a \"completed\" status since they reconstruct the final state.\n\t *\n\t * @param context - The execution context containing state and services\n\t * @param _traverser - Graph traverser (unused in replay mode)\n\t * @returns Promise resolving to the reconstructed workflow result\n\t */\n\tasync run(context: ExecutionContext<any, any>, _traverser: GraphTraverser): Promise<WorkflowResult<any>> {\n\t\tconst executionEvents = this.events.filter((event) => {\n\t\t\tif ('executionId' in event.payload) {\n\t\t\t\treturn event.payload.executionId === context.executionId\n\t\t\t}\n\t\t\treturn false\n\t\t})\n\n\t\tconst fallbackMap = new Map<string, string>()\n\n\t\tfor (const event of executionEvents) {\n\t\t\tawait this.applyEvent(event, context, fallbackMap)\n\t\t}\n\n\t\tconst includeExecutionId = executionEvents.length > 0\n\t\tconst result = await context.state.toResult(\n\t\t\tcontext.services.serializer,\n\t\t\tincludeExecutionId ? context.executionId : undefined,\n\t\t)\n\t\tresult.status = 'completed'\n\t\treturn result\n\t}\n\n\t/**\n\t * Applies a single workflow event to reconstruct the execution state.\n\t *\n\t * This method handles different event types by updating the workflow state accordingly,\n\t * including node completions, context changes, errors, fallbacks, and workflow control events.\n\t *\n\t * @param event - The workflow event to apply\n\t * @param context - The execution context to update\n\t * @param fallbackMap - Map tracking fallback node relationships (fallbackNodeId -> originalNodeId)\n\t */\n\tprivate async applyEvent(\n\t\tevent: FlowcraftEvent,\n\t\tcontext: ExecutionContext<any, any>,\n\t\tfallbackMap: Map<string, string>,\n\t): Promise<void> {\n\t\tconst { type, payload } = event\n\n\t\tswitch (type) {\n\t\t\tcase 'node:start':\n\t\t\t\tbreak\n\n\t\t\tcase 'node:finish': {\n\t\t\t\tconst originalNodeId = fallbackMap.get(payload.nodeId)\n\t\t\t\tif (originalNodeId) {\n\t\t\t\t\tawait context.state.addCompletedNode(originalNodeId, payload.result.output)\n\t\t\t\t} else {\n\t\t\t\t\tawait context.state.addCompletedNode(payload.nodeId, payload.result.output)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcase 'context:change':\n\t\t\t\tif (payload.op === 'set') {\n\t\t\t\t\tawait context.state.getContext().set(payload.key, payload.value)\n\t\t\t\t} else if (payload.op === 'delete') {\n\t\t\t\t\tawait context.state.getContext().delete(payload.key)\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tcase 'node:error':\n\t\t\t\tcontext.state.addError(payload.nodeId, payload.error)\n\t\t\t\tbreak\n\n\t\t\tcase 'node:fallback':\n\t\t\t\tfallbackMap.set(payload.fallback, payload.nodeId)\n\t\t\t\tcontext.state.markFallbackExecuted()\n\t\t\t\tbreak\n\n\t\t\tcase 'node:retry':\n\t\t\t\tbreak\n\n\t\t\tcase 'edge:evaluate':\n\t\t\t\tbreak\n\n\t\t\tcase 'workflow:stall':\n\t\t\tcase 'workflow:pause':\n\t\t\t\tif ('remainingNodes' in payload) {\n\t\t\t\t\tfor (let i = 0; i < payload.remainingNodes; i++) {\n\t\t\t\t\t\tawait context.state.markAsAwaiting(`node-${i}`)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tcase 'batch:start':\n\t\t\t\tbreak\n\n\t\t\tcase 'batch:finish':\n\t\t\t\tfor (const _result of payload.results) {\n\t\t\t\t\t// TODO?\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\tbreak\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { InMemoryEventLogger } from './chunk-
|
|
2
|
-
import { FlowRuntime } from './chunk-
|
|
1
|
+
import { InMemoryEventLogger } from './chunk-7EBKWATZ.js';
|
|
2
|
+
import { FlowRuntime } from './chunk-BEHVGFIM.js';
|
|
3
3
|
|
|
4
4
|
// src/testing/run-with-trace.ts
|
|
5
5
|
async function runWithTrace(runtime, blueprint, initialState = {}, options = {}) {
|
|
@@ -21,5 +21,5 @@ async function runWithTrace(runtime, blueprint, initialState = {}, options = {})
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export { runWithTrace };
|
|
24
|
-
//# sourceMappingURL=chunk-
|
|
25
|
-
//# sourceMappingURL=chunk-
|
|
24
|
+
//# sourceMappingURL=chunk-XZZWIJ4G.js.map
|
|
25
|
+
//# sourceMappingURL=chunk-XZZWIJ4G.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/testing/run-with-trace.ts"],"names":[],"mappings":";;;;AA+BA,eAAsB,YAAA,CACrB,SACA,SAAA,EACA,YAAA,GAA2C,EAAC,EAC5C,OAAA,GAII,EAAC,EACJ;AACD,EAAA,MAAM,WAAA,GAAc,IAAI,mBAAA,EAAoB;AAC5C,EAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY;AAAA,IACnC,GAAG,OAAA,CAAQ,OAAA;AAAA,IACX,QAAA,EAAU;AAAA,GACV,CAAA;AAED,EAAA,IAAI;AACH,IAAA,MAAM,SAAS,MAAM,WAAA,CAAY,GAAA,CAAI,SAAA,EAAW,cAAc,OAAO,CAAA;AACrE,IAAA,IAAI,OAAA,CAAQ,IAAI,KAAA,EAAO;AACtB,MAAA,WAAA,CAAY,QAAA,CAAS,CAAA,kBAAA,EAAqB,SAAA,CAAU,EAAE,CAAA,CAAE,CAAA;AAAA,IACzD;AACA,IAAA,OAAO,MAAA;AAAA,EACR,SAAS,KAAA,EAAO;AACf,IAAA,WAAA,CAAY,QAAA,CAAS,CAAA,oBAAA,EAAuB,SAAA,CAAU,EAAE,CAAA,CAAE,CAAA;AAC1D,IAAA,MAAM,KAAA;AAAA,EACP;AACD","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/testing/run-with-trace.ts"],"names":[],"mappings":";;;;AA+BA,eAAsB,YAAA,CACrB,SACA,SAAA,EACA,YAAA,GAA2C,EAAC,EAC5C,OAAA,GAII,EAAC,EACJ;AACD,EAAA,MAAM,WAAA,GAAc,IAAI,mBAAA,EAAoB;AAC5C,EAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY;AAAA,IACnC,GAAG,OAAA,CAAQ,OAAA;AAAA,IACX,QAAA,EAAU;AAAA,GACV,CAAA;AAED,EAAA,IAAI;AACH,IAAA,MAAM,SAAS,MAAM,WAAA,CAAY,GAAA,CAAI,SAAA,EAAW,cAAc,OAAO,CAAA;AACrE,IAAA,IAAI,OAAA,CAAQ,IAAI,KAAA,EAAO;AACtB,MAAA,WAAA,CAAY,QAAA,CAAS,CAAA,kBAAA,EAAqB,SAAA,CAAU,EAAE,CAAA,CAAE,CAAA;AAAA,IACzD;AACA,IAAA,OAAO,MAAA;AAAA,EACR,SAAS,KAAA,EAAO;AACf,IAAA,WAAA,CAAY,QAAA,CAAS,CAAA,oBAAA,EAAuB,SAAA,CAAU,EAAE,CAAA,CAAE,CAAA;AAC1D,IAAA,MAAM,KAAA;AAAA,EACP;AACD","file":"chunk-XZZWIJ4G.js","sourcesContent":["import { FlowRuntime } from '../runtime'\nimport type { WorkflowBlueprint } from '../types'\nimport { InMemoryEventLogger } from './event-logger'\n\n/**\n * A test helper that executes a workflow and automatically prints a detailed\n * execution trace to the console if the workflow fails.\n *\n * @example\n * // In your test file (e.g., my-workflow.test.ts)\n * it('should process data correctly', async () => {\n * const flow = createFlow('my-flow')\n * .node('a', async () => ({ output: 1 }))\n * .node('b', async ({ input }) => ({ output: input + 1 })) // Bug: returns { output: 3 }\n * .edge('a', 'b')\n *\n * const runtime = new FlowRuntime({})\n *\n * // If this test fails, a full, human-readable trace of the execution\n * // (inputs, outputs, context changes) is printed to the console.\n * const result = await runWithTrace(runtime, flow.toBlueprint())\n *\n * expect(result.context.b).toBe(2)\n * })\n *\n * @param runtime The original FlowRuntime instance (its options will be used).\n * @param blueprint The WorkflowBlueprint to execute.\n * @param initialState The initial state for the workflow run.\n * @param options Additional options for the run.\n * @returns The WorkflowResult if successful.\n */\nexport async function runWithTrace<TContext extends Record<string, any>>(\n\truntime: FlowRuntime<TContext, any>,\n\tblueprint: WorkflowBlueprint,\n\tinitialState: Partial<TContext> | string = {},\n\toptions: {\n\t\tfunctionRegistry?: Map<string, any>\n\t\tstrict?: boolean\n\t\tsignal?: AbortSignal\n\t} = {},\n) {\n\tconst eventLogger = new InMemoryEventLogger()\n\tconst testRuntime = new FlowRuntime({\n\t\t...runtime.options,\n\t\teventBus: eventLogger,\n\t})\n\n\ttry {\n\t\tconst result = await testRuntime.run(blueprint, initialState, options)\n\t\tif (process.env.DEBUG) {\n\t\t\teventLogger.printLog(`Successful Trace: ${blueprint.id}`)\n\t\t}\n\t\treturn result\n\t} catch (error) {\n\t\teventLogger.printLog(`Failing Test Trace: ${blueprint.id}`)\n\t\tthrow error\n\t}\n}\n"]}
|
|
@@ -50,22 +50,52 @@ var TrackedAsyncContext = class {
|
|
|
50
50
|
type = "async";
|
|
51
51
|
deltas = [];
|
|
52
52
|
innerContext;
|
|
53
|
-
|
|
53
|
+
eventBus;
|
|
54
|
+
executionId;
|
|
55
|
+
sourceNode;
|
|
56
|
+
constructor(innerContext, eventBus, executionId, sourceNode) {
|
|
54
57
|
this.innerContext = innerContext;
|
|
58
|
+
this.eventBus = eventBus;
|
|
59
|
+
this.executionId = executionId;
|
|
60
|
+
this.sourceNode = sourceNode;
|
|
55
61
|
}
|
|
56
62
|
async get(key) {
|
|
57
63
|
return this.innerContext.get(key);
|
|
58
64
|
}
|
|
59
65
|
async set(key, value) {
|
|
60
66
|
this.deltas.push({ op: "set", key, value });
|
|
61
|
-
|
|
67
|
+
await this.innerContext.set(key, value);
|
|
68
|
+
if (this.eventBus && this.executionId) {
|
|
69
|
+
await this.eventBus.emit({
|
|
70
|
+
type: "context:change",
|
|
71
|
+
payload: {
|
|
72
|
+
sourceNode: this.sourceNode || "unknown",
|
|
73
|
+
key,
|
|
74
|
+
op: "set",
|
|
75
|
+
value,
|
|
76
|
+
executionId: this.executionId
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
62
80
|
}
|
|
63
81
|
async has(key) {
|
|
64
82
|
return this.innerContext.has(key);
|
|
65
83
|
}
|
|
66
84
|
async delete(key) {
|
|
67
85
|
this.deltas.push({ op: "delete", key });
|
|
68
|
-
|
|
86
|
+
const result = await this.innerContext.delete(key);
|
|
87
|
+
if (this.eventBus && this.executionId && result) {
|
|
88
|
+
await this.eventBus.emit({
|
|
89
|
+
type: "context:change",
|
|
90
|
+
payload: {
|
|
91
|
+
sourceNode: this.sourceNode || "unknown",
|
|
92
|
+
key,
|
|
93
|
+
op: "delete",
|
|
94
|
+
executionId: this.executionId
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
69
99
|
}
|
|
70
100
|
toJSON() {
|
|
71
101
|
return this.innerContext.toJSON();
|
|
@@ -88,8 +118,22 @@ var TrackedAsyncContext = class {
|
|
|
88
118
|
clearDeltas() {
|
|
89
119
|
this.deltas = [];
|
|
90
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Configures the event emitter for tracking context changes.
|
|
123
|
+
* This enables the context to emit events when set/delete operations occur,
|
|
124
|
+
* allowing for external monitoring and persistence of context mutations.
|
|
125
|
+
*
|
|
126
|
+
* @param eventBus - The event bus instance to emit context change events
|
|
127
|
+
* @param executionId - The unique identifier for the current workflow execution
|
|
128
|
+
* @param sourceNode - Optional identifier for the node that triggered the context change
|
|
129
|
+
*/
|
|
130
|
+
configureEventEmitter(eventBus, executionId, sourceNode) {
|
|
131
|
+
this.eventBus = eventBus;
|
|
132
|
+
this.executionId = executionId;
|
|
133
|
+
this.sourceNode = sourceNode;
|
|
134
|
+
}
|
|
91
135
|
};
|
|
92
136
|
|
|
93
137
|
export { AsyncContextView, Context, TrackedAsyncContext };
|
|
94
|
-
//# sourceMappingURL=chunk-
|
|
95
|
-
//# sourceMappingURL=chunk-
|
|
138
|
+
//# sourceMappingURL=chunk-ZETQCNEF.js.map
|
|
139
|
+
//# sourceMappingURL=chunk-ZETQCNEF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context.ts"],"names":[],"mappings":"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","file":"chunk-ZETQCNEF.js","sourcesContent":["import type { IAsyncContext, ISyncContext, PatchOperation } from './types'\n\n/**\n * A default, high-performance, in-memory implementation of ISyncContext using a Map.\n */\nexport class Context<TContext extends Record<string, any>> implements ISyncContext<TContext> {\n\tpublic readonly type = 'sync' as const\n\tprivate data: Map<string, any>\n\n\tconstructor(initialData: Partial<TContext> = {}) {\n\t\tthis.data = new Map(Object.entries(initialData))\n\t}\n\n\tget<K extends keyof TContext>(key: K): TContext[K] | undefined\n\tget(key: string): any | undefined {\n\t\treturn this.data.get(key)\n\t}\n\n\tset<K extends keyof TContext>(key: K, value: TContext[K]): void\n\tset(key: string, value: any): void {\n\t\tthis.data.set(key, value)\n\t}\n\n\thas<K extends keyof TContext>(key: K): boolean\n\thas(key: string): boolean {\n\t\treturn this.data.has(key)\n\t}\n\n\tdelete<K extends keyof TContext>(key: K): boolean\n\tdelete(key: string): boolean {\n\t\treturn this.data.delete(key)\n\t}\n\n\ttoJSON(): Record<string, any> {\n\t\treturn Object.fromEntries(this.data)\n\t}\n}\n\n/**\n * An adapter that provides a consistent, Promise-based view of a synchronous context.\n * This is created by the runtime and is transparent to the node author.\n */\nexport class AsyncContextView<TContext extends Record<string, any>> implements IAsyncContext<TContext> {\n\tpublic readonly type = 'async' as const\n\n\tconstructor(private syncContext: ISyncContext<TContext>) {}\n\n\tget<K extends keyof TContext>(key: K): Promise<TContext[K] | undefined>\n\tget(key: string): Promise<any | undefined> {\n\t\treturn Promise.resolve(this.syncContext.get(key))\n\t}\n\n\tset<K extends keyof TContext>(key: K, value: TContext[K]): Promise<void>\n\tset(key: string, value: any): Promise<void> {\n\t\tthis.syncContext.set(key, value)\n\t\treturn Promise.resolve()\n\t}\n\n\thas<K extends keyof TContext>(key: K): Promise<boolean>\n\thas(key: string): Promise<boolean> {\n\t\treturn Promise.resolve(this.syncContext.has(key))\n\t}\n\n\tdelete<K extends keyof TContext>(key: K): Promise<boolean>\n\tdelete(key: string): Promise<boolean> {\n\t\treturn Promise.resolve(this.syncContext.delete(key))\n\t}\n\n\ttoJSON(): Promise<Record<string, any>> {\n\t\treturn Promise.resolve(this.syncContext.toJSON())\n\t}\n\n\tasync patch(_operations: PatchOperation[]): Promise<void> {\n\t\tthrow new Error('Patch operations not supported by AsyncContextView')\n\t}\n}\n\n/**\n * A proxy wrapper that tracks changes to an async context for delta-based persistence.\n * Records all mutations (set/delete operations) to enable efficient partial updates.\n */\nexport class TrackedAsyncContext<TContext extends Record<string, any>> implements IAsyncContext<TContext> {\n\tpublic readonly type = 'async' as const\n\tprivate deltas: PatchOperation[] = []\n\tprivate innerContext: IAsyncContext<TContext>\n\tprivate eventBus?: any\n\tprivate executionId?: string\n\tprivate sourceNode?: string\n\n\tconstructor(innerContext: IAsyncContext<TContext>, eventBus?: any, executionId?: string, sourceNode?: string) {\n\t\tthis.innerContext = innerContext\n\t\tthis.eventBus = eventBus\n\t\tthis.executionId = executionId\n\t\tthis.sourceNode = sourceNode\n\t}\n\n\tasync get<K extends keyof TContext>(key: K): Promise<TContext[K] | undefined>\n\tasync get(key: string): Promise<any | undefined> {\n\t\treturn this.innerContext.get(key)\n\t}\n\n\tasync set<K extends keyof TContext>(key: K, value: TContext[K]): Promise<void>\n\tasync set(key: string, value: any): Promise<void> {\n\t\tthis.deltas.push({ op: 'set', key, value })\n\t\tawait this.innerContext.set(key, value)\n\t\tif (this.eventBus && this.executionId) {\n\t\t\tawait this.eventBus.emit({\n\t\t\t\ttype: 'context:change',\n\t\t\t\tpayload: {\n\t\t\t\t\tsourceNode: this.sourceNode || 'unknown',\n\t\t\t\t\tkey,\n\t\t\t\t\top: 'set',\n\t\t\t\t\tvalue,\n\t\t\t\t\texecutionId: this.executionId,\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}\n\n\tasync has<K extends keyof TContext>(key: K): Promise<boolean>\n\tasync has(key: string): Promise<boolean> {\n\t\treturn this.innerContext.has(key)\n\t}\n\n\tasync delete<K extends keyof TContext>(key: K): Promise<boolean>\n\tasync delete(key: string): Promise<boolean> {\n\t\tthis.deltas.push({ op: 'delete', key })\n\t\tconst result = await this.innerContext.delete(key)\n\t\tif (this.eventBus && this.executionId && result) {\n\t\t\tawait this.eventBus.emit({\n\t\t\t\ttype: 'context:change',\n\t\t\t\tpayload: {\n\t\t\t\t\tsourceNode: this.sourceNode || 'unknown',\n\t\t\t\t\tkey,\n\t\t\t\t\top: 'delete',\n\t\t\t\t\texecutionId: this.executionId,\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t\treturn result\n\t}\n\n\ttoJSON(): Promise<Record<string, any>> {\n\t\treturn this.innerContext.toJSON()\n\t}\n\n\tasync patch(operations: PatchOperation[]): Promise<void> {\n\t\tif (this.innerContext.patch) {\n\t\t\treturn this.innerContext.patch(operations)\n\t\t}\n\n\t\tfor (const op of operations) {\n\t\t\tif (op.op === 'set') {\n\t\t\t\tawait this.innerContext.set(op.key, op.value)\n\t\t\t} else if (op.op === 'delete') {\n\t\t\t\tawait this.innerContext.delete(op.key)\n\t\t\t}\n\t\t}\n\t}\n\n\tgetDeltas(): PatchOperation[] {\n\t\treturn [...this.deltas]\n\t}\n\n\tclearDeltas(): void {\n\t\tthis.deltas = []\n\t}\n\n\t/**\n\t * Configures the event emitter for tracking context changes.\n\t * This enables the context to emit events when set/delete operations occur,\n\t * allowing for external monitoring and persistence of context mutations.\n\t *\n\t * @param eventBus - The event bus instance to emit context change events\n\t * @param executionId - The unique identifier for the current workflow execution\n\t * @param sourceNode - Optional identifier for the node that triggered the context change\n\t */\n\tconfigureEventEmitter(eventBus: any, executionId: string, sourceNode?: string): void {\n\t\tthis.eventBus = eventBus\n\t\tthis.executionId = executionId\n\t\tthis.sourceNode = sourceNode\n\t}\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DIContainer } from './container.js';
|
|
2
|
-
import { v as RuntimeDependencies, y as ILogger, D as ISerializer, x as IEvaluator, A as IEventBus, M as Middleware, o as NodeFunction, p as NodeClass, h as WorkflowBlueprint } from './types-
|
|
2
|
+
import { v as RuntimeDependencies, y as ILogger, D as ISerializer, x as IEvaluator, A as IEventBus, M as Middleware, o as NodeFunction, p as NodeClass, h as WorkflowBlueprint } from './types-CKhffqyb.js';
|
|
3
3
|
import './errors.js';
|
|
4
4
|
|
|
5
5
|
interface ContainerOptions<TDependencies extends RuntimeDependencies = RuntimeDependencies> {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export { createDefaultContainer } from './chunk-
|
|
2
|
-
import './chunk-
|
|
3
|
-
import './chunk-
|
|
4
|
-
import './chunk-
|
|
5
|
-
import './chunk-
|
|
1
|
+
export { createDefaultContainer } from './chunk-7M6FHFHP.js';
|
|
2
|
+
import './chunk-DV2CXHOY.js';
|
|
3
|
+
import './chunk-N63S5NEG.js';
|
|
4
|
+
import './chunk-L3MX5MTA.js';
|
|
5
|
+
import './chunk-L46TQXCV.js';
|
|
6
6
|
import './chunk-4PELJWF7.js';
|
|
7
|
-
import './chunk-
|
|
7
|
+
import './chunk-6RKHCJUU.js';
|
|
8
8
|
import './chunk-WWGFIYKW.js';
|
|
9
|
-
import './chunk-
|
|
9
|
+
import './chunk-ZETQCNEF.js';
|
|
10
10
|
import './chunk-BCRWXTWX.js';
|
|
11
11
|
import './chunk-PH2IYZHV.js';
|
|
12
12
|
//# sourceMappingURL=container-factory.js.map
|
package/dist/context.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ISyncContext, u as IAsyncContext, P as PatchOperation } from './types-
|
|
1
|
+
import { t as ISyncContext, u as IAsyncContext, P as PatchOperation } from './types-CKhffqyb.js';
|
|
2
2
|
import './errors.js';
|
|
3
3
|
import './container.js';
|
|
4
4
|
|
|
@@ -38,7 +38,10 @@ declare class TrackedAsyncContext<TContext extends Record<string, any>> implemen
|
|
|
38
38
|
readonly type: "async";
|
|
39
39
|
private deltas;
|
|
40
40
|
private innerContext;
|
|
41
|
-
|
|
41
|
+
private eventBus?;
|
|
42
|
+
private executionId?;
|
|
43
|
+
private sourceNode?;
|
|
44
|
+
constructor(innerContext: IAsyncContext<TContext>, eventBus?: any, executionId?: string, sourceNode?: string);
|
|
42
45
|
get<K extends keyof TContext>(key: K): Promise<TContext[K] | undefined>;
|
|
43
46
|
set<K extends keyof TContext>(key: K, value: TContext[K]): Promise<void>;
|
|
44
47
|
has<K extends keyof TContext>(key: K): Promise<boolean>;
|
|
@@ -47,6 +50,16 @@ declare class TrackedAsyncContext<TContext extends Record<string, any>> implemen
|
|
|
47
50
|
patch(operations: PatchOperation[]): Promise<void>;
|
|
48
51
|
getDeltas(): PatchOperation[];
|
|
49
52
|
clearDeltas(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Configures the event emitter for tracking context changes.
|
|
55
|
+
* This enables the context to emit events when set/delete operations occur,
|
|
56
|
+
* allowing for external monitoring and persistence of context mutations.
|
|
57
|
+
*
|
|
58
|
+
* @param eventBus - The event bus instance to emit context change events
|
|
59
|
+
* @param executionId - The unique identifier for the current workflow execution
|
|
60
|
+
* @param sourceNode - Optional identifier for the node that triggered the context change
|
|
61
|
+
*/
|
|
62
|
+
configureEventEmitter(eventBus: any, executionId: string, sourceNode?: string): void;
|
|
50
63
|
}
|
|
51
64
|
|
|
52
65
|
export { AsyncContextView, Context, TrackedAsyncContext };
|
package/dist/context.js
CHANGED
package/dist/error-mapper.d.ts
CHANGED
package/dist/evaluator.d.ts
CHANGED
package/dist/flow.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as NodeFunction, p as NodeClass, j as NodeDefinition, k as EdgeDefinition, h as WorkflowBlueprint, U as UIGraph } from './types-
|
|
1
|
+
import { o as NodeFunction, p as NodeClass, j as NodeDefinition, k as EdgeDefinition, h as WorkflowBlueprint, U as UIGraph } from './types-CKhffqyb.js';
|
|
2
2
|
import './errors.js';
|
|
3
3
|
import './container.js';
|
|
4
4
|
|
|
@@ -41,8 +41,8 @@ declare class FlowBuilder<TContext extends Record<string, any> = Record<string,
|
|
|
41
41
|
* @param options Configuration for the sleep duration.
|
|
42
42
|
*/
|
|
43
43
|
sleep(id: string, options: {
|
|
44
|
-
/** The duration to sleep in milliseconds. */
|
|
45
|
-
duration: number;
|
|
44
|
+
/** The duration to sleep in milliseconds or a string like '5s', '1m', '2h', '1d'. */
|
|
45
|
+
duration: number | string;
|
|
46
46
|
}): this;
|
|
47
47
|
/**
|
|
48
48
|
* Creates a wait node that pauses workflow execution for external input.
|
package/dist/flow.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { IEventStore, InMemoryEventStore, PersistentEventBusAdapter } from './adapters/persistent-event-bus.js';
|
|
1
2
|
export { BlueprintAnalysis, Cycles, analyzeBlueprint, checkForCycles, generateMermaid, generateMermaidForRun } from './analysis.js';
|
|
2
3
|
export { DIContainer, ServiceToken, ServiceTokens } from './container.js';
|
|
3
4
|
export { ContainerOptions, createDefaultContainer } from './container-factory.js';
|
|
@@ -8,9 +9,10 @@ export { PropertyEvaluator, UnsafeEvaluator } from './evaluator.js';
|
|
|
8
9
|
export { FlowBuilder, createFlow } from './flow.js';
|
|
9
10
|
export { LinterIssue, LinterIssueCode, LinterResult, lintBlueprint } from './linter.js';
|
|
10
11
|
export { ConsoleLogger, NullLogger } from './logger.js';
|
|
11
|
-
export { B as BaseNode, C as ClassNodeExecutor, s as ContextImplementation, k as EdgeDefinition, e as ExecutionServices, E as ExecutionStrategy, c as FlowRuntime, z as FlowcraftEvent, F as FunctionNodeExecutor, G as GraphTraverser, u as IAsyncContext, x as IEvaluator, A as IEventBus, y as ILogger, I as IOrchestrator, f as IRuntime, D as ISerializer, t as ISyncContext, M as Middleware, p as NodeClass, l as NodeConfig, n as NodeContext, j as NodeDefinition, N as NodeExecutionResult, b as NodeExecutor, a as NodeExecutorConfig, d as NodeExecutorFactory, o as NodeFunction, q as NodeImplementation, r as NodeRegistry, m as NodeResult, P as PatchOperation, R as ReadyNode, v as RuntimeDependencies, w as RuntimeOptions, S as SourceLocation, U as UIGraph, h as WorkflowBlueprint, g as WorkflowBlueprintMetadata, H as WorkflowError, K as WorkflowResult, W as WorkflowState, J as WorkflowStatus, i as isNodeClass } from './types-
|
|
12
|
+
export { B as BaseNode, C as ClassNodeExecutor, s as ContextImplementation, k as EdgeDefinition, e as ExecutionServices, E as ExecutionStrategy, c as FlowRuntime, z as FlowcraftEvent, F as FunctionNodeExecutor, G as GraphTraverser, u as IAsyncContext, x as IEvaluator, A as IEventBus, y as ILogger, I as IOrchestrator, f as IRuntime, D as ISerializer, t as ISyncContext, M as Middleware, p as NodeClass, l as NodeConfig, n as NodeContext, j as NodeDefinition, N as NodeExecutionResult, b as NodeExecutor, a as NodeExecutorConfig, d as NodeExecutorFactory, o as NodeFunction, q as NodeImplementation, r as NodeRegistry, m as NodeResult, P as PatchOperation, R as ReadyNode, v as RuntimeDependencies, w as RuntimeOptions, S as SourceLocation, U as UIGraph, h as WorkflowBlueprint, g as WorkflowBlueprintMetadata, H as WorkflowError, K as WorkflowResult, W as WorkflowState, J as WorkflowStatus, i as isNodeClass } from './types-CKhffqyb.js';
|
|
12
13
|
export { AdapterOptions, BaseDistributedAdapter, ICoordinationStore, JobPayload } from './runtime/adapter.js';
|
|
13
14
|
export { DefaultOrchestrator } from './runtime/orchestrator.js';
|
|
15
|
+
export { ReplayOrchestrator } from './runtime/orchestrators/replay.js';
|
|
14
16
|
export { executeBatch, processResults } from './runtime/orchestrators/utils.js';
|
|
15
17
|
export { sanitizeBlueprint } from './sanitizer.js';
|
|
16
18
|
export { JsonSerializer } from './serializer.js';
|