flowcraft 1.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -134
- package/dist/analysis.d.ts +43 -0
- package/dist/analysis.js +3 -0
- package/dist/chunk-4PELJWF7.js +29 -0
- package/dist/chunk-4PELJWF7.js.map +1 -0
- package/dist/chunk-55J6XMHW.js +3 -0
- package/dist/{chunk-7XUN3OQT.js.map → chunk-55J6XMHW.js.map} +1 -1
- package/dist/chunk-5EHIPX23.js +202 -0
- package/dist/chunk-5EHIPX23.js.map +1 -0
- package/dist/chunk-5QMPFUKA.js +40 -0
- package/dist/chunk-5QMPFUKA.js.map +1 -0
- package/dist/chunk-5ZWYSKMH.js +147 -0
- package/dist/chunk-5ZWYSKMH.js.map +1 -0
- package/dist/chunk-5ZXV3R5D.js +28 -0
- package/dist/chunk-5ZXV3R5D.js.map +1 -0
- package/dist/chunk-CO5BTPKI.js +410 -0
- package/dist/chunk-CO5BTPKI.js.map +1 -0
- package/dist/chunk-CSZ6EOWG.js +61 -0
- package/dist/chunk-CSZ6EOWG.js.map +1 -0
- package/dist/chunk-CYHZ2YVH.js +24 -0
- package/dist/chunk-CYHZ2YVH.js.map +1 -0
- package/dist/chunk-DSYAC4WB.js +27 -0
- package/dist/chunk-DSYAC4WB.js.map +1 -0
- package/dist/chunk-HMR2GEGE.js +3 -0
- package/dist/{chunk-F2RSES6P.js.map → chunk-HMR2GEGE.js.map} +1 -1
- package/dist/chunk-HN72TZY5.js +110 -0
- package/dist/chunk-HN72TZY5.js.map +1 -0
- package/dist/chunk-KWQHFT7E.js +49 -0
- package/dist/chunk-KWQHFT7E.js.map +1 -0
- package/dist/chunk-PH2IYZHV.js +48 -0
- package/dist/chunk-PH2IYZHV.js.map +1 -0
- package/dist/chunk-QRMUKDSP.js +141 -0
- package/dist/chunk-QRMUKDSP.js.map +1 -0
- package/dist/chunk-UETC63DP.js +65 -0
- package/dist/chunk-UETC63DP.js.map +1 -0
- package/dist/chunk-UMXW3TCY.js +165 -0
- package/dist/chunk-UMXW3TCY.js.map +1 -0
- package/dist/context.d.ts +23 -105
- package/dist/context.js +1 -1
- package/dist/errors.d.ts +15 -31
- package/dist/errors.js +1 -1
- package/dist/evaluator.d.ts +30 -0
- package/dist/evaluator.js +3 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/flow.d.ts +55 -0
- package/dist/flow.js +4 -0
- package/dist/flow.js.map +1 -0
- package/dist/index.d.ts +15 -16
- package/dist/index.js +17 -25
- package/dist/linter.d.ts +24 -0
- package/dist/linter.js +4 -0
- package/dist/linter.js.map +1 -0
- package/dist/logger.d.ts +15 -40
- package/dist/logger.js +1 -1
- package/dist/node.d.ts +1 -0
- package/dist/node.js +3 -0
- package/dist/node.js.map +1 -0
- package/dist/runtime/adapter.d.ts +94 -0
- package/dist/runtime/adapter.js +15 -0
- package/dist/runtime/adapter.js.map +1 -0
- package/dist/runtime/executors.d.ts +26 -0
- package/dist/runtime/executors.js +4 -0
- package/dist/runtime/executors.js.map +1 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.js +16 -0
- package/dist/runtime/runtime.d.ts +34 -0
- package/dist/runtime/runtime.js +14 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/runtime/state.d.ts +21 -0
- package/dist/runtime/state.js +4 -0
- package/dist/runtime/state.js.map +1 -0
- package/dist/runtime/traverser.d.ts +25 -0
- package/dist/runtime/traverser.js +5 -0
- package/dist/runtime/traverser.js.map +1 -0
- package/dist/runtime/types.d.ts +15 -0
- package/dist/runtime/types.js +3 -0
- package/dist/sanitizer.d.ts +10 -0
- package/dist/sanitizer.js +3 -0
- package/dist/{utils/sanitize.js.map → sanitizer.js.map} +1 -1
- package/dist/serializer.d.ts +16 -0
- package/dist/serializer.js +3 -0
- package/dist/serializer.js.map +1 -0
- package/dist/types-lG3xCzp_.d.ts +206 -0
- package/dist/types.d.ts +1 -3
- package/dist/types.js +1 -1
- package/package.json +10 -21
- package/LICENSE +0 -21
- package/dist/builder/graph/graph.d.ts +0 -57
- package/dist/builder/graph/graph.js +0 -21
- package/dist/builder/graph/graph.js.map +0 -1
- package/dist/builder/graph/index.d.ts +0 -8
- package/dist/builder/graph/index.js +0 -23
- package/dist/builder/graph/internal-nodes.d.ts +0 -59
- package/dist/builder/graph/internal-nodes.js +0 -20
- package/dist/builder/graph/internal-nodes.js.map +0 -1
- package/dist/builder/graph/runner.d.ts +0 -51
- package/dist/builder/graph/runner.js +0 -21
- package/dist/builder/graph/runner.js.map +0 -1
- package/dist/builder/graph/types.d.ts +0 -3
- package/dist/builder/graph/types.js +0 -3
- package/dist/builder/index.d.ts +0 -8
- package/dist/builder/index.js +0 -24
- package/dist/builder/index.js.map +0 -1
- package/dist/builder/patterns.d.ts +0 -136
- package/dist/builder/patterns.js +0 -19
- package/dist/builder/patterns.js.map +0 -1
- package/dist/chunk-3YMBNZ77.js +0 -441
- package/dist/chunk-3YMBNZ77.js.map +0 -1
- package/dist/chunk-64DNBF5W.js +0 -36
- package/dist/chunk-64DNBF5W.js.map +0 -1
- package/dist/chunk-6QCXIRLA.js +0 -18
- package/dist/chunk-6QCXIRLA.js.map +0 -1
- package/dist/chunk-7XUN3OQT.js +0 -3
- package/dist/chunk-AOHBHYF6.js +0 -7
- package/dist/chunk-AOHBHYF6.js.map +0 -1
- package/dist/chunk-BRFMFLR6.js +0 -85
- package/dist/chunk-BRFMFLR6.js.map +0 -1
- package/dist/chunk-ELEHMJPM.js +0 -13
- package/dist/chunk-ELEHMJPM.js.map +0 -1
- package/dist/chunk-F2RSES6P.js +0 -3
- package/dist/chunk-F6C6J7HK.js +0 -3
- package/dist/chunk-F6C6J7HK.js.map +0 -1
- package/dist/chunk-GMKJ34T2.js +0 -3
- package/dist/chunk-GMKJ34T2.js.map +0 -1
- package/dist/chunk-HEO3XL4Z.js +0 -328
- package/dist/chunk-HEO3XL4Z.js.map +0 -1
- package/dist/chunk-IIKTTIW5.js +0 -56
- package/dist/chunk-IIKTTIW5.js.map +0 -1
- package/dist/chunk-KOBEU2EM.js +0 -3
- package/dist/chunk-KOBEU2EM.js.map +0 -1
- package/dist/chunk-L5PK5VL2.js +0 -178
- package/dist/chunk-L5PK5VL2.js.map +0 -1
- package/dist/chunk-P3RPDZHO.js +0 -36
- package/dist/chunk-P3RPDZHO.js.map +0 -1
- package/dist/chunk-PNWOW52F.js +0 -19
- package/dist/chunk-PNWOW52F.js.map +0 -1
- package/dist/chunk-R27FIYR5.js +0 -62
- package/dist/chunk-R27FIYR5.js.map +0 -1
- package/dist/chunk-S4WFNGQG.js +0 -17
- package/dist/chunk-S4WFNGQG.js.map +0 -1
- package/dist/chunk-TS3M7MWA.js +0 -3
- package/dist/chunk-TS3M7MWA.js.map +0 -1
- package/dist/chunk-UY4PNPBX.js +0 -156
- package/dist/chunk-UY4PNPBX.js.map +0 -1
- package/dist/chunk-VMH2LRM6.js +0 -114
- package/dist/chunk-VMH2LRM6.js.map +0 -1
- package/dist/chunk-VZDHIOCH.js +0 -76
- package/dist/chunk-VZDHIOCH.js.map +0 -1
- package/dist/chunk-WGVHM7DU.js +0 -66
- package/dist/chunk-WGVHM7DU.js.map +0 -1
- package/dist/chunk-WR5PDOPP.js +0 -91
- package/dist/chunk-WR5PDOPP.js.map +0 -1
- package/dist/chunk-YR433ZDA.js +0 -20
- package/dist/chunk-YR433ZDA.js.map +0 -1
- package/dist/executors/in-memory.d.ts +0 -39
- package/dist/executors/in-memory.js +0 -6
- package/dist/executors/in-memory.js.map +0 -1
- package/dist/executors/types.d.ts +0 -3
- package/dist/executors/types.js +0 -3
- package/dist/executors/types.js.map +0 -1
- package/dist/functions.d.ts +0 -88
- package/dist/functions.js +0 -21
- package/dist/functions.js.map +0 -1
- package/dist/types-U76Ukj96.d.ts +0 -609
- package/dist/utils/analysis.d.ts +0 -75
- package/dist/utils/analysis.js +0 -3
- package/dist/utils/index.d.ts +0 -8
- package/dist/utils/index.js +0 -10
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/mermaid.d.ts +0 -46
- package/dist/utils/mermaid.js +0 -4
- package/dist/utils/mermaid.js.map +0 -1
- package/dist/utils/middleware.d.ts +0 -11
- package/dist/utils/middleware.js +0 -3
- package/dist/utils/middleware.js.map +0 -1
- package/dist/utils/sanitize.d.ts +0 -19
- package/dist/utils/sanitize.js +0 -3
- package/dist/utils/sleep.d.ts +0 -9
- package/dist/utils/sleep.js +0 -4
- package/dist/utils/sleep.js.map +0 -1
- package/dist/workflow/AbstractNode.d.ts +0 -3
- package/dist/workflow/AbstractNode.js +0 -4
- package/dist/workflow/AbstractNode.js.map +0 -1
- package/dist/workflow/Flow.d.ts +0 -3
- package/dist/workflow/Flow.js +0 -16
- package/dist/workflow/Flow.js.map +0 -1
- package/dist/workflow/Node.d.ts +0 -3
- package/dist/workflow/Node.js +0 -15
- package/dist/workflow/Node.js.map +0 -1
- package/dist/workflow/index.d.ts +0 -4
- package/dist/workflow/index.js +0 -18
- package/dist/workflow/index.js.map +0 -1
- package/dist/workflow/node-patterns.d.ts +0 -55
- package/dist/workflow/node-patterns.js +0 -16
- package/dist/workflow/node-patterns.js.map +0 -1
- package/dist/workflow/registry.d.ts +0 -17
- package/dist/workflow/registry.js +0 -3
- package/dist/workflow/registry.js.map +0 -1
- /package/dist/{utils/analysis.js.map → analysis.js.map} +0 -0
- /package/dist/{builder/graph → runtime}/index.js.map +0 -0
- /package/dist/{builder/graph → runtime}/types.js.map +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { analyzeBlueprint } from './chunk-HN72TZY5.js';
|
|
2
|
+
|
|
3
|
+
// src/linter.ts
|
|
4
|
+
function lintBlueprint(blueprint, registry) {
|
|
5
|
+
const issues = [];
|
|
6
|
+
const nodeIds = new Set(blueprint.nodes.map((n) => n.id));
|
|
7
|
+
const registryKeys = registry instanceof Map ? new Set(registry.keys()) : new Set(Object.keys(registry));
|
|
8
|
+
for (const node of blueprint.nodes) {
|
|
9
|
+
if (!node.uses.startsWith("batch-") && !node.uses.startsWith("loop-") && !registryKeys.has(node.uses)) {
|
|
10
|
+
issues.push({
|
|
11
|
+
code: "MISSING_NODE_IMPLEMENTATION",
|
|
12
|
+
message: `Node implementation key '${node.uses}' is not found in the provided registry.`,
|
|
13
|
+
nodeId: node.id
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
for (const edge of blueprint.edges || []) {
|
|
18
|
+
if (!nodeIds.has(edge.source)) {
|
|
19
|
+
issues.push({
|
|
20
|
+
code: "INVALID_EDGE_SOURCE",
|
|
21
|
+
message: `Edge source '${edge.source}' does not correspond to a valid node ID.`,
|
|
22
|
+
relatedId: edge.target
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (!nodeIds.has(edge.target)) {
|
|
26
|
+
issues.push({
|
|
27
|
+
code: "INVALID_EDGE_TARGET",
|
|
28
|
+
message: `Edge target '${edge.target}' does not correspond to a valid node ID.`,
|
|
29
|
+
relatedId: edge.source
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (blueprint.nodes.length > 1) {
|
|
34
|
+
const analysis = analyzeBlueprint(blueprint);
|
|
35
|
+
const connectedNodes = /* @__PURE__ */ new Set();
|
|
36
|
+
const nodesToVisit = [...analysis.startNodeIds];
|
|
37
|
+
const visited = /* @__PURE__ */ new Set();
|
|
38
|
+
while (nodesToVisit.length > 0) {
|
|
39
|
+
const currentId = nodesToVisit.pop();
|
|
40
|
+
if (!currentId || visited.has(currentId)) continue;
|
|
41
|
+
visited.add(currentId);
|
|
42
|
+
connectedNodes.add(currentId);
|
|
43
|
+
for (const e of blueprint.edges.filter((e2) => e2.source === currentId)) {
|
|
44
|
+
nodesToVisit.push(e.target);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
for (const nodeId of nodeIds) {
|
|
48
|
+
if (!connectedNodes.has(nodeId)) {
|
|
49
|
+
issues.push({
|
|
50
|
+
code: "ORPHAN_NODE",
|
|
51
|
+
message: `Node '${nodeId}' is not reachable from any start node.`,
|
|
52
|
+
nodeId
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
isValid: issues.length === 0,
|
|
59
|
+
issues
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { lintBlueprint };
|
|
64
|
+
//# sourceMappingURL=chunk-UETC63DP.js.map
|
|
65
|
+
//# sourceMappingURL=chunk-UETC63DP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/linter.ts"],"names":["e"],"mappings":"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","file":"chunk-UETC63DP.js","sourcesContent":["import { analyzeBlueprint } from './analysis'\nimport type { NodeClass, NodeFunction, WorkflowBlueprint } from './types'\n\nexport type LinterIssueCode =\n\t| 'INVALID_EDGE_SOURCE'\n\t| 'INVALID_EDGE_TARGET'\n\t| 'MISSING_NODE_IMPLEMENTATION'\n\t| 'ORPHAN_NODE'\n\nexport interface LinterIssue {\n\tcode: LinterIssueCode\n\tmessage: string\n\tnodeId?: string\n\trelatedId?: string\n}\n\nexport interface LinterResult {\n\tisValid: boolean\n\tissues: LinterIssue[]\n}\n\n/**\n * Statically analyzes a workflow blueprint against a registry of implementations\n * to find common errors before runtime.\n *\n * @param blueprint The WorkflowBlueprint to analyze.\n * @param registry A map of node implementations (functions or classes) to check against.\n * @returns A LinterResult object containing any issues found.\n */\nexport function lintBlueprint(\n\tblueprint: WorkflowBlueprint,\n\tregistry: Map<string, NodeFunction | NodeClass> | Record<string, NodeFunction | NodeClass>,\n): LinterResult {\n\tconst issues: LinterIssue[] = []\n\tconst nodeIds = new Set(blueprint.nodes.map((n) => n.id))\n\tconst registryKeys = registry instanceof Map ? new Set(registry.keys()) : new Set(Object.keys(registry))\n\n\t// check for missing node implementations\n\tfor (const node of blueprint.nodes) {\n\t\tif (!node.uses.startsWith('batch-') && !node.uses.startsWith('loop-') && !registryKeys.has(node.uses)) {\n\t\t\tissues.push({\n\t\t\t\tcode: 'MISSING_NODE_IMPLEMENTATION',\n\t\t\t\tmessage: `Node implementation key '${node.uses}' is not found in the provided registry.`,\n\t\t\t\tnodeId: node.id,\n\t\t\t})\n\t\t}\n\t}\n\n\t// check for graph integrity (edges must point to valid nodes)\n\tfor (const edge of blueprint.edges || []) {\n\t\tif (!nodeIds.has(edge.source)) {\n\t\t\tissues.push({\n\t\t\t\tcode: 'INVALID_EDGE_SOURCE',\n\t\t\t\tmessage: `Edge source '${edge.source}' does not correspond to a valid node ID.`,\n\t\t\t\trelatedId: edge.target,\n\t\t\t})\n\t\t}\n\t\tif (!nodeIds.has(edge.target)) {\n\t\t\tissues.push({\n\t\t\t\tcode: 'INVALID_EDGE_TARGET',\n\t\t\t\tmessage: `Edge target '${edge.target}' does not correspond to a valid node ID.`,\n\t\t\t\trelatedId: edge.source,\n\t\t\t})\n\t\t}\n\t}\n\n\t// check for orphan nodes (not connected to the main graph)\n\tif (blueprint.nodes.length > 1) {\n\t\tconst analysis = analyzeBlueprint(blueprint)\n\t\tconst connectedNodes = new Set<string>()\n\t\tconst nodesToVisit = [...analysis.startNodeIds]\n\t\tconst visited = new Set<string>()\n\n\t\twhile (nodesToVisit.length > 0) {\n\t\t\tconst currentId = nodesToVisit.pop()\n\t\t\tif (!currentId || visited.has(currentId)) continue\n\n\t\t\tvisited.add(currentId)\n\t\t\tconnectedNodes.add(currentId)\n\n\t\t\tfor (const e of blueprint.edges.filter((e) => e.source === currentId)) {\n\t\t\t\tnodesToVisit.push(e.target)\n\t\t\t}\n\t\t}\n\n\t\tfor (const nodeId of nodeIds) {\n\t\t\tif (!connectedNodes.has(nodeId)) {\n\t\t\t\tissues.push({\n\t\t\t\t\tcode: 'ORPHAN_NODE',\n\t\t\t\t\tmessage: `Node '${nodeId}' is not reachable from any start node.`,\n\t\t\t\t\tnodeId,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tisValid: issues.length === 0,\n\t\tissues,\n\t}\n}\n"]}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { CancelledWorkflowError } from './chunk-5ZXV3R5D.js';
|
|
2
|
+
import { analyzeBlueprint } from './chunk-HN72TZY5.js';
|
|
3
|
+
|
|
4
|
+
// src/runtime/traverser.ts
|
|
5
|
+
var GraphTraverser = class {
|
|
6
|
+
constructor(blueprint, runtime, state, functionRegistry, executionId, signal, concurrency) {
|
|
7
|
+
this.runtime = runtime;
|
|
8
|
+
this.state = state;
|
|
9
|
+
this.functionRegistry = functionRegistry;
|
|
10
|
+
this.executionId = executionId;
|
|
11
|
+
this.signal = signal;
|
|
12
|
+
this.concurrency = concurrency;
|
|
13
|
+
this.dynamicBlueprint = structuredClone(blueprint);
|
|
14
|
+
this.allPredecessors = /* @__PURE__ */ new Map();
|
|
15
|
+
for (const node of this.dynamicBlueprint.nodes) {
|
|
16
|
+
this.allPredecessors.set(node.id, /* @__PURE__ */ new Set());
|
|
17
|
+
}
|
|
18
|
+
for (const edge of this.dynamicBlueprint.edges) {
|
|
19
|
+
this.allPredecessors.get(edge.target)?.add(edge.source);
|
|
20
|
+
}
|
|
21
|
+
const analysis = analyzeBlueprint(blueprint);
|
|
22
|
+
this.frontier = new Set(analysis.startNodeIds.filter((id) => !this.isFallbackNode(id)));
|
|
23
|
+
if (this.frontier.size === 0 && analysis.cycles.length > 0 && this.runtime.options.strict !== true) {
|
|
24
|
+
const uniqueStartNodes = /* @__PURE__ */ new Set();
|
|
25
|
+
for (const cycle of analysis.cycles) {
|
|
26
|
+
if (cycle.length > 0) uniqueStartNodes.add(cycle[0]);
|
|
27
|
+
}
|
|
28
|
+
this.frontier = new Set(uniqueStartNodes);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
frontier = /* @__PURE__ */ new Set();
|
|
32
|
+
allPredecessors;
|
|
33
|
+
dynamicBlueprint;
|
|
34
|
+
isFallbackNode(nodeId) {
|
|
35
|
+
return this.dynamicBlueprint.nodes.some((n) => n.config?.fallback === nodeId);
|
|
36
|
+
}
|
|
37
|
+
async traverse() {
|
|
38
|
+
try {
|
|
39
|
+
this.signal?.throwIfAborted();
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (error instanceof DOMException && error.name === "AbortError")
|
|
42
|
+
throw new CancelledWorkflowError("Workflow cancelled");
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
let iterations = 0;
|
|
46
|
+
const maxIterations = 1e4;
|
|
47
|
+
while (this.frontier.size > 0) {
|
|
48
|
+
if (++iterations > maxIterations) throw new Error("Traversal exceeded maximum iterations, possible infinite loop");
|
|
49
|
+
try {
|
|
50
|
+
this.signal?.throwIfAborted();
|
|
51
|
+
const currentJobs = Array.from(this.frontier);
|
|
52
|
+
this.frontier.clear();
|
|
53
|
+
const settledResults = await this.executeWithConcurrency(currentJobs);
|
|
54
|
+
const completedThisTurn = /* @__PURE__ */ new Set();
|
|
55
|
+
for (const promiseResult of settledResults) {
|
|
56
|
+
if (promiseResult.status === "rejected") {
|
|
57
|
+
const { nodeId: nodeId2, error } = promiseResult.reason;
|
|
58
|
+
if (error instanceof CancelledWorkflowError) throw error;
|
|
59
|
+
this.state.addError(nodeId2, error);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const { nodeId, result } = promiseResult.value;
|
|
63
|
+
this.state.addCompletedNode(nodeId, result.output);
|
|
64
|
+
completedThisTurn.add(nodeId);
|
|
65
|
+
if (result._fallbackExecuted) this.state.markFallbackExecuted();
|
|
66
|
+
await this.handleDynamicNodes(nodeId, result);
|
|
67
|
+
if (!result._fallbackExecuted) {
|
|
68
|
+
const matched = await this.runtime.determineNextNodes(
|
|
69
|
+
this.dynamicBlueprint,
|
|
70
|
+
nodeId,
|
|
71
|
+
result,
|
|
72
|
+
this.state.getContext()
|
|
73
|
+
);
|
|
74
|
+
const loopControllerMatch = matched.find((m) => m.node.uses === "loop-controller");
|
|
75
|
+
const finalMatched = loopControllerMatch ? [loopControllerMatch] : matched;
|
|
76
|
+
for (const { node, edge } of finalMatched) {
|
|
77
|
+
const joinStrategy = node.config?.joinStrategy || "all";
|
|
78
|
+
if (joinStrategy !== "any" && this.state.getCompletedNodes().has(node.id)) continue;
|
|
79
|
+
await this.runtime.applyEdgeTransform(edge, result, node, this.state.getContext(), this.allPredecessors);
|
|
80
|
+
const requiredPredecessors = this.allPredecessors.get(node.id);
|
|
81
|
+
if (!requiredPredecessors) continue;
|
|
82
|
+
const isReady = joinStrategy === "any" ? [...requiredPredecessors].some((p) => completedThisTurn.has(p)) : [...requiredPredecessors].every((p) => this.state.getCompletedNodes().has(p));
|
|
83
|
+
if (isReady) this.frontier.add(node.id);
|
|
84
|
+
}
|
|
85
|
+
if (matched.length === 0) {
|
|
86
|
+
for (const [potentialNextId, predecessors] of this.allPredecessors) {
|
|
87
|
+
if (predecessors.has(nodeId) && !this.state.getCompletedNodes().has(potentialNextId)) {
|
|
88
|
+
const joinStrategy = this.dynamicBlueprint.nodes.find((n) => n.id === potentialNextId)?.config?.joinStrategy || "all";
|
|
89
|
+
const isReady = joinStrategy === "any" ? [...predecessors].some((p) => completedThisTurn.has(p)) : [...predecessors].every((p) => this.state.getCompletedNodes().has(p));
|
|
90
|
+
if (isReady) this.frontier.add(potentialNextId);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
98
|
+
throw new CancelledWorkflowError("Workflow cancelled");
|
|
99
|
+
}
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async executeWithConcurrency(nodeIds) {
|
|
105
|
+
const maxConcurrency = this.concurrency || nodeIds.length;
|
|
106
|
+
const results = [];
|
|
107
|
+
for (let i = 0; i < nodeIds.length; i += maxConcurrency) {
|
|
108
|
+
const batch = nodeIds.slice(i, i + maxConcurrency);
|
|
109
|
+
const batchPromises = batch.map(async (nodeId) => {
|
|
110
|
+
try {
|
|
111
|
+
const result = await this.runtime.executeNode(
|
|
112
|
+
this.dynamicBlueprint,
|
|
113
|
+
nodeId,
|
|
114
|
+
this.state,
|
|
115
|
+
this.allPredecessors,
|
|
116
|
+
this.functionRegistry,
|
|
117
|
+
this.executionId,
|
|
118
|
+
this.signal
|
|
119
|
+
);
|
|
120
|
+
results.push({
|
|
121
|
+
status: "fulfilled",
|
|
122
|
+
value: { nodeId, result }
|
|
123
|
+
});
|
|
124
|
+
} catch (error) {
|
|
125
|
+
results.push({
|
|
126
|
+
status: "rejected",
|
|
127
|
+
reason: { nodeId, error }
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
await Promise.all(batchPromises);
|
|
132
|
+
}
|
|
133
|
+
return results;
|
|
134
|
+
}
|
|
135
|
+
async handleDynamicNodes(nodeId, result) {
|
|
136
|
+
if (result.dynamicNodes && result.dynamicNodes.length > 0) {
|
|
137
|
+
const gatherNodeId = result.output?.gatherNodeId;
|
|
138
|
+
for (const dynamicNode of result.dynamicNodes) {
|
|
139
|
+
this.dynamicBlueprint.nodes.push(dynamicNode);
|
|
140
|
+
this.allPredecessors.set(dynamicNode.id, /* @__PURE__ */ new Set([nodeId]));
|
|
141
|
+
if (gatherNodeId) {
|
|
142
|
+
this.allPredecessors.get(gatherNodeId)?.add(dynamicNode.id);
|
|
143
|
+
}
|
|
144
|
+
this.frontier.add(dynamicNode.id);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
getAllNodeIds() {
|
|
149
|
+
return new Set(this.dynamicBlueprint.nodes.map((n) => n.id));
|
|
150
|
+
}
|
|
151
|
+
getFallbackNodeIds() {
|
|
152
|
+
const fallbackNodeIds = /* @__PURE__ */ new Set();
|
|
153
|
+
for (const node of this.dynamicBlueprint.nodes) {
|
|
154
|
+
if (node.config?.fallback) fallbackNodeIds.add(node.config.fallback);
|
|
155
|
+
}
|
|
156
|
+
return fallbackNodeIds;
|
|
157
|
+
}
|
|
158
|
+
getDynamicBlueprint() {
|
|
159
|
+
return this.dynamicBlueprint;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export { GraphTraverser };
|
|
164
|
+
//# sourceMappingURL=chunk-UMXW3TCY.js.map
|
|
165
|
+
//# sourceMappingURL=chunk-UMXW3TCY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/traverser.ts"],"names":["nodeId"],"mappings":"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","file":"chunk-UMXW3TCY.js","sourcesContent":["import { analyzeBlueprint } from '../analysis'\nimport { CancelledWorkflowError } from '../errors'\nimport type { NodeResult, WorkflowBlueprint } from '../types'\nimport type { WorkflowState } from './state'\nimport type { IRuntime } from './types'\n\nexport class GraphTraverser<TContext extends Record<string, any>, TDependencies extends Record<string, any>> {\n\tprivate frontier = new Set<string>()\n\tprivate allPredecessors: Map<string, Set<string>>\n\tprivate dynamicBlueprint: WorkflowBlueprint\n\n\tconstructor(\n\t\tblueprint: WorkflowBlueprint,\n\t\tprivate runtime: IRuntime<TContext, TDependencies>,\n\t\tprivate state: WorkflowState<TContext>,\n\t\tprivate functionRegistry: Map<string, any> | undefined,\n\t\tprivate executionId: string,\n\t\tprivate signal?: AbortSignal,\n\t\tprivate concurrency?: number,\n\t) {\n\t\tthis.dynamicBlueprint = structuredClone(blueprint) as WorkflowBlueprint\n\t\tthis.allPredecessors = new Map<string, Set<string>>()\n\t\tfor (const node of this.dynamicBlueprint.nodes) {\n\t\t\tthis.allPredecessors.set(node.id, new Set())\n\t\t}\n\t\tfor (const edge of this.dynamicBlueprint.edges) {\n\t\t\tthis.allPredecessors.get(edge.target)?.add(edge.source)\n\t\t}\n\t\tconst analysis = analyzeBlueprint(blueprint)\n\t\tthis.frontier = new Set(analysis.startNodeIds.filter((id) => !this.isFallbackNode(id)))\n\t\tif (this.frontier.size === 0 && analysis.cycles.length > 0 && this.runtime.options.strict !== true) {\n\t\t\tconst uniqueStartNodes = new Set<string>()\n\t\t\tfor (const cycle of analysis.cycles) {\n\t\t\t\tif (cycle.length > 0) uniqueStartNodes.add(cycle[0])\n\t\t\t}\n\t\t\tthis.frontier = new Set(uniqueStartNodes)\n\t\t}\n\t}\n\n\tprivate isFallbackNode(nodeId: string): boolean {\n\t\treturn this.dynamicBlueprint.nodes.some((n) => n.config?.fallback === nodeId)\n\t}\n\n\tasync traverse(): Promise<void> {\n\t\ttry {\n\t\t\tthis.signal?.throwIfAborted()\n\t\t} catch (error) {\n\t\t\tif (error instanceof DOMException && error.name === 'AbortError')\n\t\t\t\tthrow new CancelledWorkflowError('Workflow cancelled')\n\t\t\tthrow error\n\t\t}\n\t\tlet iterations = 0\n\t\tconst maxIterations = 10000\n\t\twhile (this.frontier.size > 0) {\n\t\t\tif (++iterations > maxIterations) throw new Error('Traversal exceeded maximum iterations, possible infinite loop')\n\n\t\t\ttry {\n\t\t\t\tthis.signal?.throwIfAborted()\n\t\t\t\tconst currentJobs = Array.from(this.frontier)\n\t\t\t\tthis.frontier.clear()\n\t\t\t\tconst settledResults = await this.executeWithConcurrency(currentJobs)\n\t\t\t\tconst completedThisTurn = new Set<string>()\n\t\t\t\tfor (const promiseResult of settledResults) {\n\t\t\t\t\tif (promiseResult.status === 'rejected') {\n\t\t\t\t\t\tconst { nodeId, error } = promiseResult.reason\n\t\t\t\t\t\tif (error instanceof CancelledWorkflowError) throw error\n\t\t\t\t\t\tthis.state.addError(nodeId, error as Error)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst { nodeId, result } = promiseResult.value\n\t\t\t\t\tthis.state.addCompletedNode(nodeId, result.output)\n\t\t\t\t\tcompletedThisTurn.add(nodeId)\n\t\t\t\t\tif (result._fallbackExecuted) this.state.markFallbackExecuted()\n\t\t\t\t\tawait this.handleDynamicNodes(nodeId, result)\n\t\t\t\t\tif (!result._fallbackExecuted) {\n\t\t\t\t\t\tconst matched = await this.runtime.determineNextNodes(\n\t\t\t\t\t\t\tthis.dynamicBlueprint,\n\t\t\t\t\t\t\tnodeId,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\tthis.state.getContext(),\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\t// If one of the next nodes is a loop controller, prioritize it to avoid ambiguity from manual cycle edges.\n\t\t\t\t\t\tconst loopControllerMatch = matched.find((m) => m.node.uses === 'loop-controller')\n\t\t\t\t\t\tconst finalMatched = loopControllerMatch ? [loopControllerMatch] : matched\n\n\t\t\t\t\t\tfor (const { node, edge } of finalMatched) {\n\t\t\t\t\t\t\tconst joinStrategy = node.config?.joinStrategy || 'all'\n\t\t\t\t\t\t\tif (joinStrategy !== 'any' && this.state.getCompletedNodes().has(node.id)) continue\n\t\t\t\t\t\t\tawait this.runtime.applyEdgeTransform(edge, result, node, this.state.getContext(), this.allPredecessors)\n\t\t\t\t\t\t\tconst requiredPredecessors = this.allPredecessors.get(node.id)\n\t\t\t\t\t\t\tif (!requiredPredecessors) continue\n\t\t\t\t\t\t\tconst isReady =\n\t\t\t\t\t\t\t\tjoinStrategy === 'any'\n\t\t\t\t\t\t\t\t\t? [...requiredPredecessors].some((p) => completedThisTurn.has(p))\n\t\t\t\t\t\t\t\t\t: [...requiredPredecessors].every((p) => this.state.getCompletedNodes().has(p))\n\t\t\t\t\t\t\tif (isReady) this.frontier.add(node.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (matched.length === 0) {\n\t\t\t\t\t\t\tfor (const [potentialNextId, predecessors] of this.allPredecessors) {\n\t\t\t\t\t\t\t\tif (predecessors.has(nodeId) && !this.state.getCompletedNodes().has(potentialNextId)) {\n\t\t\t\t\t\t\t\t\tconst joinStrategy =\n\t\t\t\t\t\t\t\t\t\tthis.dynamicBlueprint.nodes.find((n) => n.id === potentialNextId)?.config?.joinStrategy || 'all'\n\t\t\t\t\t\t\t\t\tconst isReady =\n\t\t\t\t\t\t\t\t\t\tjoinStrategy === 'any'\n\t\t\t\t\t\t\t\t\t\t\t? [...predecessors].some((p) => completedThisTurn.has(p))\n\t\t\t\t\t\t\t\t\t\t\t: [...predecessors].every((p) => this.state.getCompletedNodes().has(p))\n\t\t\t\t\t\t\t\t\tif (isReady) this.frontier.add(potentialNextId)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DOMException && error.name === 'AbortError') {\n\t\t\t\t\tthrow new CancelledWorkflowError('Workflow cancelled')\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async executeWithConcurrency(\n\t\tnodeIds: string[],\n\t): Promise<\n\t\tArray<\n\t\t\t| { status: 'fulfilled'; value: { nodeId: string; result: NodeResult<any, any> } }\n\t\t\t| { status: 'rejected'; reason: { nodeId: string; error: unknown } }\n\t\t>\n\t> {\n\t\tconst maxConcurrency = this.concurrency || nodeIds.length\n\t\tconst results: Array<\n\t\t\t| { status: 'fulfilled'; value: { nodeId: string; result: NodeResult<any, any> } }\n\t\t\t| { status: 'rejected'; reason: { nodeId: string; error: unknown } }\n\t\t> = []\n\n\t\tfor (let i = 0; i < nodeIds.length; i += maxConcurrency) {\n\t\t\tconst batch = nodeIds.slice(i, i + maxConcurrency)\n\t\t\tconst batchPromises = batch.map(async (nodeId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await this.runtime.executeNode(\n\t\t\t\t\t\tthis.dynamicBlueprint,\n\t\t\t\t\t\tnodeId,\n\t\t\t\t\t\tthis.state,\n\t\t\t\t\t\tthis.allPredecessors,\n\t\t\t\t\t\tthis.functionRegistry,\n\t\t\t\t\t\tthis.executionId,\n\t\t\t\t\t\tthis.signal,\n\t\t\t\t\t)\n\t\t\t\t\tresults.push({\n\t\t\t\t\t\tstatus: 'fulfilled' as const,\n\t\t\t\t\t\tvalue: { nodeId, result },\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tresults.push({\n\t\t\t\t\t\tstatus: 'rejected' as const,\n\t\t\t\t\t\treason: { nodeId, error },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tawait Promise.all(batchPromises)\n\t\t}\n\n\t\treturn results\n\t}\n\n\tprivate async handleDynamicNodes(nodeId: string, result: NodeResult<any, any>) {\n\t\tif (result.dynamicNodes && result.dynamicNodes.length > 0) {\n\t\t\tconst gatherNodeId = result.output?.gatherNodeId\n\t\t\tfor (const dynamicNode of result.dynamicNodes) {\n\t\t\t\tthis.dynamicBlueprint.nodes.push(dynamicNode)\n\t\t\t\tthis.allPredecessors.set(dynamicNode.id, new Set([nodeId]))\n\t\t\t\tif (gatherNodeId) {\n\t\t\t\t\tthis.allPredecessors.get(gatherNodeId)?.add(dynamicNode.id)\n\t\t\t\t}\n\t\t\t\tthis.frontier.add(dynamicNode.id)\n\t\t\t}\n\t\t}\n\t}\n\n\tgetAllNodeIds(): Set<string> {\n\t\treturn new Set(this.dynamicBlueprint.nodes.map((n) => n.id))\n\t}\n\n\tgetFallbackNodeIds(): Set<string> {\n\t\tconst fallbackNodeIds = new Set<string>()\n\t\tfor (const node of this.dynamicBlueprint.nodes) {\n\t\t\tif (node.config?.fallback) fallbackNodeIds.add(node.config.fallback)\n\t\t}\n\t\treturn fallbackNodeIds\n\t}\n\n\tgetDynamicBlueprint(): WorkflowBlueprint {\n\t\treturn this.dynamicBlueprint\n\t}\n}\n"]}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,113 +1,31 @@
|
|
|
1
|
+
import { I as ISyncContext, h as IAsyncContext } from './types-lG3xCzp_.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
* A
|
|
3
|
-
* Using a `ContextKey` provides compile-time safety for your workflow's state.
|
|
4
|
-
* @template T The type of the value this key refers to.
|
|
5
|
-
*/
|
|
6
|
-
type ContextKey<T> = symbol & {
|
|
7
|
-
__type: T;
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* Creates a new, unique `ContextKey` for type-safe access to the `Context`.
|
|
11
|
-
* @template T The type of the value this key will hold.
|
|
12
|
-
* @param description An optional description for debugging purposes (e.g., in logs or test snapshots).
|
|
13
|
-
* @returns A unique `ContextKey<T>`.
|
|
14
|
-
*/
|
|
15
|
-
declare const contextKey: <T>(description?: string) => ContextKey<T>;
|
|
16
|
-
/**
|
|
17
|
-
* Defines the interface for the shared context object passed through the workflow.
|
|
18
|
-
* This interface is "async-aware", allowing for both synchronous (Map-based)
|
|
19
|
-
* and asynchronous (e.g., Redis-backed) implementations.
|
|
20
|
-
*/
|
|
21
|
-
interface Context {
|
|
22
|
-
/**
|
|
23
|
-
* Asynchronously retrieves a value from the context.
|
|
24
|
-
* Callers should ALWAYS `await` the result of this method.
|
|
25
|
-
*/
|
|
26
|
-
get: (<T>(key: ContextKey<T>) => Promise<T | undefined>) & (<T = any>(key: string) => Promise<T | undefined>);
|
|
27
|
-
/** Asynchronously stores a value in the context. */
|
|
28
|
-
set: (<T>(key: ContextKey<T>, value: T) => Promise<this>) & ((key: string, value: any) => Promise<this>);
|
|
29
|
-
/** Asynchronously checks if a key exists in the context. */
|
|
30
|
-
has: ((key: ContextKey<any>) => Promise<boolean>) & ((key: string) => Promise<boolean>);
|
|
31
|
-
/** Asynchronously deletes a key from the context. */
|
|
32
|
-
delete: ((key: ContextKey<any>) => Promise<boolean>) & ((key: string) => Promise<boolean>);
|
|
33
|
-
/**
|
|
34
|
-
* Returns an iterator of all [key, value] pairs in the context.
|
|
35
|
-
* NOTE: This may not be supported or may be inefficient in some async implementations.
|
|
36
|
-
*/
|
|
37
|
-
entries: () => IterableIterator<[any, any]>;
|
|
38
|
-
/**
|
|
39
|
-
* Returns an iterator of all keys in the context.
|
|
40
|
-
* NOTE: This may not be supported or may be inefficient in some async implementations.
|
|
41
|
-
*/
|
|
42
|
-
keys: () => IterableIterator<any>;
|
|
43
|
-
/**
|
|
44
|
-
* Returns an iterator of all values in the context.
|
|
45
|
-
* NOTE: This may not be supported or may be inefficient in some async implementations.
|
|
46
|
-
*/
|
|
47
|
-
values: () => IterableIterator<any>;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* The default, `Map`-based implementation of the `Context` interface.
|
|
51
|
-
* Its methods are async to satisfy the `Context` interface, but they wrap
|
|
52
|
-
* synchronous operations.
|
|
4
|
+
* A default, high-performance, in-memory implementation of ISyncContext using a Map.
|
|
53
5
|
*/
|
|
54
|
-
declare class
|
|
6
|
+
declare class Context<TContext extends Record<string, any>> implements ISyncContext<TContext> {
|
|
7
|
+
readonly type: "sync";
|
|
55
8
|
private data;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
set(key: ContextKey<any> | string, value: any): Promise<this>;
|
|
63
|
-
has(key: ContextKey<any> | string): Promise<boolean>;
|
|
64
|
-
delete(key: ContextKey<any> | string): Promise<boolean>;
|
|
65
|
-
entries(): IterableIterator<[any, any]>;
|
|
66
|
-
keys(): IterableIterator<any>;
|
|
67
|
-
values(): IterableIterator<any>;
|
|
9
|
+
constructor(initialData?: Partial<TContext>);
|
|
10
|
+
get<K extends keyof TContext>(key: K): TContext[K] | undefined;
|
|
11
|
+
set<K extends keyof TContext>(key: K, value: TContext[K]): void;
|
|
12
|
+
has<K extends keyof TContext>(key: K): boolean;
|
|
13
|
+
delete<K extends keyof TContext>(key: K): boolean;
|
|
14
|
+
toJSON(): Record<string, any>;
|
|
68
15
|
}
|
|
69
|
-
/** A function that takes a `Context` and returns a (potentially new) `Context`. */
|
|
70
|
-
type ContextTransform = (ctx: Context) => Context | Promise<Context>;
|
|
71
16
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* @template T The type of the value the lens focuses on.
|
|
17
|
+
* An adapter that provides a consistent, Promise-based view of a synchronous context.
|
|
18
|
+
* This is created by the runtime and is transparent to the node author.
|
|
75
19
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
20
|
+
declare class AsyncContextView<TContext extends Record<string, any>> implements IAsyncContext<TContext> {
|
|
21
|
+
private syncContext;
|
|
22
|
+
readonly type: "async";
|
|
23
|
+
constructor(syncContext: ISyncContext<TContext>);
|
|
24
|
+
get<K extends keyof TContext>(key: K): Promise<TContext[K] | undefined>;
|
|
25
|
+
set<K extends keyof TContext>(key: K, value: TContext[K]): Promise<void>;
|
|
26
|
+
has<K extends keyof TContext>(key: K): Promise<boolean>;
|
|
27
|
+
delete<K extends keyof TContext>(key: K): Promise<boolean>;
|
|
28
|
+
toJSON(): Promise<Record<string, any>>;
|
|
83
29
|
}
|
|
84
|
-
/**
|
|
85
|
-
* Creates a `ContextLens` object for a specific `ContextKey`.
|
|
86
|
-
* This is the entry point for functional context manipulation.
|
|
87
|
-
* All operations that read from the context are now async.
|
|
88
|
-
*
|
|
89
|
-
* @example
|
|
90
|
-
* const NAME = contextKey<string>('name')
|
|
91
|
-
* const nameLens = lens(NAME)
|
|
92
|
-
*
|
|
93
|
-
* // Usage in an async function:
|
|
94
|
-
* async function exampleUsage(ctx: Context) {
|
|
95
|
-
* const currentName = await nameLens.get(ctx);
|
|
96
|
-
* const setNameTransform = nameLens.set('Alice');
|
|
97
|
-
* await setNameTransform(ctx);
|
|
98
|
-
* }
|
|
99
|
-
*
|
|
100
|
-
* @param key The `ContextKey` to focus on.
|
|
101
|
-
* @returns A `ContextLens<T>` object with async-aware methods.
|
|
102
|
-
*/
|
|
103
|
-
declare function lens<T>(key: ContextKey<T>): ContextLens<T>;
|
|
104
|
-
/**
|
|
105
|
-
* Composes multiple `ContextTransform` functions into a single `ContextTransform` function.
|
|
106
|
-
* The transformations are applied in the order they are provided.
|
|
107
|
-
*
|
|
108
|
-
* @param transforms A sequence of `ContextTransform` functions.
|
|
109
|
-
* @returns A single function that applies all transformations.
|
|
110
|
-
*/
|
|
111
|
-
declare function composeContext(...transforms: ContextTransform[]): ContextTransform;
|
|
112
30
|
|
|
113
|
-
export {
|
|
31
|
+
export { AsyncContextView, Context };
|
package/dist/context.js
CHANGED
package/dist/errors.d.ts
CHANGED
|
@@ -1,35 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/** Error thrown when a node fails during execution. */
|
|
2
|
+
declare class NodeExecutionError extends Error {
|
|
3
|
+
readonly nodeId: string;
|
|
4
|
+
readonly blueprintId: string;
|
|
5
|
+
readonly originalError?: Error | undefined;
|
|
6
|
+
readonly executionId?: string | undefined;
|
|
7
|
+
constructor(message: string, nodeId: string, blueprintId: string, originalError?: Error | undefined, executionId?: string | undefined);
|
|
7
8
|
}
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
declare class WorkflowError extends Error {
|
|
13
|
-
readonly nodeName: string;
|
|
14
|
-
readonly phase: 'prep' | 'exec' | 'post';
|
|
15
|
-
readonly originalError?: Error;
|
|
16
|
-
/**
|
|
17
|
-
* @param message The error message.
|
|
18
|
-
* @param nodeName The name of the `Node` class where the error occurred.
|
|
19
|
-
* @param phase The lifecycle phase (`'prep'`, `'exec'`, or `'post'`) where the error was thrown.
|
|
20
|
-
* @param originalError The underlying error that was caught and wrapped.
|
|
21
|
-
*/
|
|
22
|
-
constructor(message: string, nodeName: string, phase: 'prep' | 'exec' | 'post', originalError?: Error);
|
|
9
|
+
/** Error thrown when a workflow is gracefully aborted. */
|
|
10
|
+
declare class CancelledWorkflowError extends Error {
|
|
11
|
+
readonly executionId?: string | undefined;
|
|
12
|
+
constructor(message?: string, executionId?: string | undefined);
|
|
23
13
|
}
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* When an executor catches this error, it should immediately terminate the
|
|
28
|
-
* entire workflow run, bypassing any remaining retries, fallbacks, or
|
|
29
|
-
* subsequent nodes in the graph.
|
|
30
|
-
*/
|
|
31
|
-
declare class FatalWorkflowError extends WorkflowError {
|
|
32
|
-
constructor(message: string, nodeName: string, phase: 'prep' | 'exec' | 'post', originalError?: Error);
|
|
14
|
+
/** Error thrown for a non-recoverable failure that should halt the workflow immediately. */
|
|
15
|
+
declare class FatalNodeExecutionError extends NodeExecutionError {
|
|
16
|
+
constructor(message: string, nodeId: string, blueprintId: string, originalError?: Error, executionId?: string);
|
|
33
17
|
}
|
|
34
18
|
|
|
35
|
-
export {
|
|
19
|
+
export { CancelledWorkflowError, FatalNodeExecutionError, NodeExecutionError };
|
package/dist/errors.js
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { k as IEvaluator } from './types-lG3xCzp_.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A safe evaluator that only allows simple property access.
|
|
5
|
+
* It cannot execute arbitrary code and is secure for untrusted inputs.
|
|
6
|
+
*
|
|
7
|
+
* Example expressions:
|
|
8
|
+
* - "result.output.status"
|
|
9
|
+
* - "context.user.isAdmin"
|
|
10
|
+
* - "input.value"
|
|
11
|
+
*/
|
|
12
|
+
declare class PropertyEvaluator implements IEvaluator {
|
|
13
|
+
evaluate(expression: string, context: Record<string, any>): any;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @warning This evaluator uses `new Function()` and can execute arbitrary
|
|
17
|
+
* JavaScript code. It poses a significant security risk if the expressions
|
|
18
|
+
* are not from a trusted source (e.g., user input).
|
|
19
|
+
*
|
|
20
|
+
* It should only be used in controlled environments where all workflow
|
|
21
|
+
* definitions are static and authored by trusted developers.
|
|
22
|
+
*
|
|
23
|
+
* For safer evaluation, use the default `PropertyEvaluator` or install a
|
|
24
|
+
* sandboxed library like `jsep` to create a custom, secure evaluator.
|
|
25
|
+
*/
|
|
26
|
+
declare class UnsafeEvaluator implements IEvaluator {
|
|
27
|
+
evaluate(expression: string, context: Record<string, any>): any;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { PropertyEvaluator, UnsafeEvaluator };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"evaluator.js"}
|
package/dist/flow.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { d as NodeFunction, e as NodeClass, N as NodeDefinition, E as EdgeDefinition, W as WorkflowBlueprint } from './types-lG3xCzp_.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A fluent API for programmatically constructing a WorkflowBlueprint.
|
|
5
|
+
*/
|
|
6
|
+
declare class Flow<TContext extends Record<string, any> = Record<string, any>, TDependencies extends Record<string, any> = Record<string, any>> {
|
|
7
|
+
private blueprint;
|
|
8
|
+
private functionRegistry;
|
|
9
|
+
private loopControllerIds;
|
|
10
|
+
private loopDefinitions;
|
|
11
|
+
constructor(id: string);
|
|
12
|
+
node<TInput = any, TOutput = any, TAction extends string = string>(id: string, implementation: NodeFunction<TContext, TDependencies, TInput, TOutput, TAction> | NodeClass<TContext, TDependencies, TInput, TOutput, TAction>, options?: Omit<NodeDefinition, 'id' | 'uses'>): this;
|
|
13
|
+
edge(source: string, target: string, options?: Omit<EdgeDefinition, 'source' | 'target'>): this;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a batch processing pattern.
|
|
16
|
+
* It takes an input array, runs a worker node on each item in parallel, and gathers the results.
|
|
17
|
+
* @param id The base ID for this batch operation.
|
|
18
|
+
* @param worker The node implementation to run on each item.
|
|
19
|
+
* @param options Configuration for the batch operation.
|
|
20
|
+
* @param options.inputKey The key in the context that holds the input array for the batch.
|
|
21
|
+
* @param options.outputKey The key in the context where the array of results will be stored.
|
|
22
|
+
* @returns The Flow instance for chaining.
|
|
23
|
+
*/
|
|
24
|
+
batch<TInput = any, TOutput = any, TAction extends string = string>(id: string, worker: NodeFunction<TContext, TDependencies, TInput, TOutput, TAction> | NodeClass<TContext, TDependencies, TInput, TOutput, TAction>, options: {
|
|
25
|
+
/** The key in the context that holds the input array for the batch. */
|
|
26
|
+
inputKey: string;
|
|
27
|
+
/** The key in the context where the array of results will be stored. */
|
|
28
|
+
outputKey: string;
|
|
29
|
+
}): this;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a loop pattern in the workflow graph.
|
|
32
|
+
* @param id A unique identifier for the loop construct.
|
|
33
|
+
* @param options Defines the start, end, and continuation condition of the loop.
|
|
34
|
+
* @param options.startNodeId The ID of the first node inside the loop body.
|
|
35
|
+
* @param options.endNodeId The ID of the last node inside the loop body.
|
|
36
|
+
* @param options.condition An expression that, if true, causes the loop to run again.
|
|
37
|
+
*/
|
|
38
|
+
loop(id: string, options: {
|
|
39
|
+
/** The ID of the first node inside the loop body. */
|
|
40
|
+
startNodeId: string;
|
|
41
|
+
/** The ID of the last node inside the loop body. */
|
|
42
|
+
endNodeId: string;
|
|
43
|
+
/** An expression that, if true, causes the loop to run again. */
|
|
44
|
+
condition: string;
|
|
45
|
+
}): this;
|
|
46
|
+
getLoopControllerId(id: string): string;
|
|
47
|
+
toBlueprint(): WorkflowBlueprint;
|
|
48
|
+
getFunctionRegistry(): Map<string, NodeClass | NodeFunction>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Helper function to create a new Flow builder instance.
|
|
52
|
+
*/
|
|
53
|
+
declare function createFlow<TContext extends Record<string, any> = Record<string, any>, TDependencies extends Record<string, any> = Record<string, any>>(id: string): Flow<TContext, TDependencies>;
|
|
54
|
+
|
|
55
|
+
export { Flow, createFlow };
|
package/dist/flow.js
ADDED
package/dist/flow.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"flow.js"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
14
|
-
export {
|
|
15
|
-
|
|
16
|
-
export { sleep } from './utils/sleep.js';
|
|
1
|
+
export { BlueprintAnalysis, Cycles, analyzeBlueprint, checkForCycles, generateMermaid } from './analysis.js';
|
|
2
|
+
export { AsyncContextView, Context } from './context.js';
|
|
3
|
+
export { CancelledWorkflowError, FatalNodeExecutionError, NodeExecutionError } from './errors.js';
|
|
4
|
+
export { PropertyEvaluator, UnsafeEvaluator } from './evaluator.js';
|
|
5
|
+
export { Flow, createFlow } from './flow.js';
|
|
6
|
+
export { LinterIssue, LinterIssueCode, LinterResult, lintBlueprint } from './linter.js';
|
|
7
|
+
export { ConsoleLogger, NullLogger } from './logger.js';
|
|
8
|
+
export { B as BaseNode, C as ContextImplementation, E as EdgeDefinition, h as IAsyncContext, k as IEvaluator, m as IEventBus, l as ILogger, n as ISerializer, I as ISyncContext, M as Middleware, e as NodeClass, a as NodeConfig, c as NodeContext, N as NodeDefinition, d as NodeFunction, f as NodeImplementation, g as NodeRegistry, b as NodeResult, R as RuntimeDependencies, j as RuntimeOptions, W as WorkflowBlueprint, o as WorkflowError, p as WorkflowResult, i as isNodeClass } from './types-lG3xCzp_.js';
|
|
9
|
+
export { AdapterOptions, BaseDistributedAdapter, ICoordinationStore, JobPayload } from './runtime/adapter.js';
|
|
10
|
+
export { BuiltInNodeExecutor, ClassNodeExecutor, ExecutionStrategy, FunctionNodeExecutor } from './runtime/executors.js';
|
|
11
|
+
export { FlowRuntime } from './runtime/runtime.js';
|
|
12
|
+
export { WorkflowState } from './runtime/state.js';
|
|
13
|
+
export { GraphTraverser } from './runtime/traverser.js';
|
|
14
|
+
export { sanitizeBlueprint } from './sanitizer.js';
|
|
15
|
+
import './runtime/types.js';
|