flowcraft 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/dist/analysis.d.ts +3 -2
  4. package/dist/analysis.js +1 -1
  5. package/dist/{chunk-HN72TZY5.js → chunk-233SESC2.js} +34 -23
  6. package/dist/chunk-233SESC2.js.map +1 -0
  7. package/dist/{chunk-UETC63DP.js → chunk-EUJWJWFA.js} +24 -4
  8. package/dist/chunk-EUJWJWFA.js.map +1 -0
  9. package/dist/{chunk-NBIRTKZ7.js → chunk-GEKDR2SS.js} +14 -5
  10. package/dist/chunk-GEKDR2SS.js.map +1 -0
  11. package/dist/{chunk-3XVVR2SR.js → chunk-OTS5YJ3S.js} +97 -20
  12. package/dist/chunk-OTS5YJ3S.js.map +1 -0
  13. package/dist/{chunk-O3XD45IL.js → chunk-QLGJUDQF.js} +42 -15
  14. package/dist/chunk-QLGJUDQF.js.map +1 -0
  15. package/dist/{chunk-KWQHFT7E.js → chunk-R3HQXIEL.js} +6 -6
  16. package/dist/chunk-R3HQXIEL.js.map +1 -0
  17. package/dist/{chunk-CSZ6EOWG.js → chunk-VSGQDLBF.js} +3 -3
  18. package/dist/chunk-VSGQDLBF.js.map +1 -0
  19. package/dist/{chunk-4A627Q6L.js → chunk-ZCHFZBGL.js} +24 -7
  20. package/dist/chunk-ZCHFZBGL.js.map +1 -0
  21. package/dist/context.d.ts +1 -1
  22. package/dist/context.js +1 -1
  23. package/dist/evaluator.d.ts +1 -1
  24. package/dist/flow.d.ts +18 -7
  25. package/dist/flow.js +1 -1
  26. package/dist/index.d.ts +2 -1
  27. package/dist/index.js +8 -8
  28. package/dist/linter.d.ts +3 -3
  29. package/dist/linter.js +2 -2
  30. package/dist/logger.d.ts +1 -1
  31. package/dist/node.d.ts +1 -1
  32. package/dist/runtime/adapter.d.ts +5 -2
  33. package/dist/runtime/adapter.js +6 -6
  34. package/dist/runtime/builtin-keys.d.ts +38 -0
  35. package/dist/runtime/builtin-keys.js +10 -0
  36. package/dist/runtime/builtin-keys.js.map +1 -0
  37. package/dist/runtime/executors.d.ts +1 -1
  38. package/dist/runtime/index.d.ts +2 -1
  39. package/dist/runtime/index.js +6 -6
  40. package/dist/runtime/runtime.d.ts +9 -3
  41. package/dist/runtime/runtime.js +5 -5
  42. package/dist/runtime/state.d.ts +1 -1
  43. package/dist/runtime/state.js +2 -2
  44. package/dist/runtime/traverser.d.ts +1 -1
  45. package/dist/runtime/traverser.js +2 -2
  46. package/dist/runtime/types.d.ts +2 -2
  47. package/dist/sanitizer.d.ts +1 -1
  48. package/dist/serializer.d.ts +1 -1
  49. package/dist/{types-CQCe_nBM.d.ts → types-CsTeXTiA.d.ts} +16 -8
  50. package/dist/types.d.ts +1 -1
  51. package/package.json +51 -51
  52. package/dist/chunk-3XVVR2SR.js.map +0 -1
  53. package/dist/chunk-4A627Q6L.js.map +0 -1
  54. package/dist/chunk-CSZ6EOWG.js.map +0 -1
  55. package/dist/chunk-HN72TZY5.js.map +0 -1
  56. package/dist/chunk-KWQHFT7E.js.map +0 -1
  57. package/dist/chunk-NBIRTKZ7.js.map +0 -1
  58. package/dist/chunk-O3XD45IL.js.map +0 -1
  59. package/dist/chunk-UETC63DP.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/runtime/builtin-keys.ts"],"names":[],"mappings":";AAIO,IAAM,YAAA,GAAe;AAAA,EAC3B,eAAA,EAAiB,CAAC,cAAA,EAAgB,SAAS,CAAA;AAAA,EAC3C,cAAA,EAAgB,CAAC,cAAA,EAAgB,SAAS;AAAA;AAE3C","file":"builtin-keys.js","sourcesContent":["/**\n * A registry defining the dynamic context keys set by each built-in node.\n * This object is the single source of truth.\n */\nexport const BUILTIN_KEYS = {\n\t'batch-scatter': ['currentIndex', 'hasMore'],\n\t'batch-gather': ['allWorkerIds', 'hasMore'],\n\t// 'loop-controller': ['loopCounter']\n} as const\n\n/**\n * A comprehensive map of all possible dynamic keys to their corresponding TypeScript types.\n * The compiler will enforce that any key used in `BUILTIN_KEYS` must have an entry here.\n */\ntype DynamicKeyTypeMap = {\n\tcurrentIndex: number\n\thasMore: boolean\n\tallWorkerIds: string[]\n\t// loopCounter: number\n}\n\n/**\n * A utility type that creates a union of all possible dynamic key strings\n * by flattening the values of the `BUILTIN_KEYS` object.\n *\n * Example: 'currentIndex' | 'hasMore' | 'allWorkerIds'\n */\ntype AllDynamicKeyStrings = (typeof BUILTIN_KEYS)[keyof typeof BUILTIN_KEYS][number]\n\n/**\n * The final, dynamically generated `DynamicKeys` type.\n *\n * It uses a mapped type to construct an object where:\n * - The keys are the union of all strings from `AllDynamicKeyStrings`.\n * - The value for each key is looked up from our central `DynamicKeyTypeMap`.\n *\n * This ensures that `DynamicKeys` is always perfectly in sync with `BUILTIN_KEYS`.\n */\nexport type DynamicKeys = {\n\t[K in AllDynamicKeyStrings]: DynamicKeyTypeMap[K]\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { N as NodeDefinition, c as NodeContext, b as NodeResult, d as NodeFunction, m as IEventBus, e as NodeClass, C as ContextImplementation } from '../types-CQCe_nBM.js';
1
+ import { N as NodeDefinition, c as NodeContext, b as NodeResult, d as NodeFunction, m as IEventBus, e as NodeClass, C as ContextImplementation } from '../types-CsTeXTiA.js';
2
2
 
3
3
  interface ExecutionStrategy {
4
4
  execute: (nodeDef: NodeDefinition, context: NodeContext<any, any, any>, executionId?: string, signal?: AbortSignal) => Promise<NodeResult<any, any>>;
@@ -3,5 +3,6 @@ export { BuiltInNodeExecutor, ClassNodeExecutor, ExecutionStrategy, FunctionNode
3
3
  export { FlowRuntime } from './runtime.js';
4
4
  export { WorkflowState } from './state.js';
5
5
  export { GraphTraverser } from './traverser.js';
6
- import '../types-CQCe_nBM.js';
6
+ import '../types-CsTeXTiA.js';
7
+ import './builtin-keys.js';
7
8
  import './types.js';
@@ -1,16 +1,16 @@
1
1
  import '../chunk-HMR2GEGE.js';
2
- export { BaseDistributedAdapter } from '../chunk-O3XD45IL.js';
3
- export { FlowRuntime } from '../chunk-3XVVR2SR.js';
4
- export { WorkflowState } from '../chunk-CSZ6EOWG.js';
5
- export { GraphTraverser } from '../chunk-NBIRTKZ7.js';
2
+ export { BaseDistributedAdapter } from '../chunk-QLGJUDQF.js';
3
+ export { FlowRuntime } from '../chunk-OTS5YJ3S.js';
4
+ export { WorkflowState } from '../chunk-VSGQDLBF.js';
5
+ export { GraphTraverser } from '../chunk-GEKDR2SS.js';
6
6
  import '../chunk-DSYAC4WB.js';
7
7
  import '../chunk-CYHZ2YVH.js';
8
8
  export { BuiltInNodeExecutor, ClassNodeExecutor, FunctionNodeExecutor } from '../chunk-M2FRTT2K.js';
9
- import '../chunk-KWQHFT7E.js';
9
+ import '../chunk-R3HQXIEL.js';
10
10
  import '../chunk-5ZXV3R5D.js';
11
11
  import '../chunk-PH2IYZHV.js';
12
12
  import '../chunk-U5V5O5MN.js';
13
- import '../chunk-HN72TZY5.js';
13
+ import '../chunk-233SESC2.js';
14
14
  import '../chunk-4PELJWF7.js';
15
15
  //# sourceMappingURL=index.js.map
16
16
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,9 @@
1
- import { d as NodeFunction, e as NodeClass, B as BaseNode, j as RuntimeOptions, W as WorkflowBlueprint, p as WorkflowResult, b as NodeResult, C as ContextImplementation, N as NodeDefinition, E as EdgeDefinition } from '../types-CQCe_nBM.js';
1
+ import { d as NodeFunction, e as NodeClass, B as BaseNode, j as RuntimeOptions, W as WorkflowBlueprint, p as WorkflowResult, b as NodeResult, C as ContextImplementation, N as NodeDefinition, E as EdgeDefinition } from '../types-CsTeXTiA.js';
2
+ import { DynamicKeys } from './builtin-keys.js';
2
3
  import { WorkflowState } from './state.js';
3
4
  import { IRuntime } from './types.js';
4
5
 
6
+ type InternalFlowContext<TContext extends Record<string, any>> = TContext & Partial<DynamicKeys>;
5
7
  declare class FlowRuntime<TContext extends Record<string, any>, TDependencies extends Record<string, any>> implements IRuntime<TContext, TDependencies> {
6
8
  registry: Record<string, NodeFunction | NodeClass | typeof BaseNode>;
7
9
  private blueprints;
@@ -11,6 +13,10 @@ declare class FlowRuntime<TContext extends Record<string, any>, TDependencies ex
11
13
  private serializer;
12
14
  private middleware;
13
15
  private evaluator;
16
+ /**
17
+ * Cache for blueprint analysis results to avoid recomputing for the same blueprint object.
18
+ * Uses WeakMap to allow garbage collection of unused blueprints.
19
+ */
14
20
  private analysisCache;
15
21
  options: RuntimeOptions<TDependencies>;
16
22
  constructor(options: RuntimeOptions<TDependencies>);
@@ -23,13 +29,13 @@ declare class FlowRuntime<TContext extends Record<string, any>, TDependencies ex
23
29
  executeNode(blueprint: WorkflowBlueprint, nodeId: string, state: WorkflowState<TContext>, allPredecessors?: Map<string, Set<string>>, functionRegistry?: Map<string, any>, executionId?: string, signal?: AbortSignal): Promise<NodeResult<any, any>>;
24
30
  private getExecutor;
25
31
  private executeWithFallback;
26
- determineNextNodes(blueprint: WorkflowBlueprint, nodeId: string, result: NodeResult<any, any>, context: ContextImplementation<TContext>): Promise<{
32
+ determineNextNodes(blueprint: WorkflowBlueprint, nodeId: string, result: NodeResult<any, any>, context: ContextImplementation<TContext>, executionId?: string): Promise<{
27
33
  node: NodeDefinition;
28
34
  edge: EdgeDefinition;
29
35
  }[]>;
30
36
  applyEdgeTransform(edge: EdgeDefinition, sourceResult: NodeResult<any, any>, targetNode: NodeDefinition, context: ContextImplementation<TContext>, allPredecessors?: Map<string, Set<string>>): Promise<void>;
31
37
  private _resolveNodeInput;
32
- protected _executeBuiltInNode(nodeDef: NodeDefinition, contextImpl: ContextImplementation<TContext>): Promise<NodeResult<any, any>>;
38
+ protected _executeBuiltInNode(nodeDef: NodeDefinition, contextImpl: ContextImplementation<InternalFlowContext<TContext>>, functionRegistry?: Map<string, any>): Promise<NodeResult<any, any>>;
33
39
  }
34
40
 
35
41
  export { FlowRuntime };
@@ -1,14 +1,14 @@
1
- export { FlowRuntime } from '../chunk-3XVVR2SR.js';
2
- import '../chunk-CSZ6EOWG.js';
3
- import '../chunk-NBIRTKZ7.js';
1
+ export { FlowRuntime } from '../chunk-OTS5YJ3S.js';
2
+ import '../chunk-VSGQDLBF.js';
3
+ import '../chunk-GEKDR2SS.js';
4
4
  import '../chunk-DSYAC4WB.js';
5
5
  import '../chunk-CYHZ2YVH.js';
6
6
  import '../chunk-M2FRTT2K.js';
7
- import '../chunk-KWQHFT7E.js';
7
+ import '../chunk-R3HQXIEL.js';
8
8
  import '../chunk-5ZXV3R5D.js';
9
9
  import '../chunk-PH2IYZHV.js';
10
10
  import '../chunk-U5V5O5MN.js';
11
- import '../chunk-HN72TZY5.js';
11
+ import '../chunk-233SESC2.js';
12
12
  import '../chunk-4PELJWF7.js';
13
13
  //# sourceMappingURL=runtime.js.map
14
14
  //# sourceMappingURL=runtime.js.map
@@ -1,4 +1,4 @@
1
- import { C as ContextImplementation, o as WorkflowError, p as WorkflowResult, n as ISerializer } from '../types-CQCe_nBM.js';
1
+ import { C as ContextImplementation, o as WorkflowError, p as WorkflowResult, n as ISerializer } from '../types-CsTeXTiA.js';
2
2
 
3
3
  declare class WorkflowState<TContext extends Record<string, any>> {
4
4
  private _completedNodes;
@@ -1,4 +1,4 @@
1
- export { WorkflowState } from '../chunk-CSZ6EOWG.js';
2
- import '../chunk-KWQHFT7E.js';
1
+ export { WorkflowState } from '../chunk-VSGQDLBF.js';
2
+ import '../chunk-R3HQXIEL.js';
3
3
  //# sourceMappingURL=state.js.map
4
4
  //# sourceMappingURL=state.js.map
@@ -1,4 +1,4 @@
1
- import { W as WorkflowBlueprint } from '../types-CQCe_nBM.js';
1
+ import { W as WorkflowBlueprint } from '../types-CsTeXTiA.js';
2
2
  import { WorkflowState } from './state.js';
3
3
  import { IRuntime } from './types.js';
4
4
 
@@ -1,5 +1,5 @@
1
- export { GraphTraverser } from '../chunk-NBIRTKZ7.js';
1
+ export { GraphTraverser } from '../chunk-GEKDR2SS.js';
2
2
  import '../chunk-5ZXV3R5D.js';
3
- import '../chunk-HN72TZY5.js';
3
+ import '../chunk-233SESC2.js';
4
4
  //# sourceMappingURL=traverser.js.map
5
5
  //# sourceMappingURL=traverser.js.map
@@ -1,4 +1,4 @@
1
- import { R as RuntimeDependencies, j as RuntimeOptions, W as WorkflowBlueprint, b as NodeResult, C as ContextImplementation, N as NodeDefinition, E as EdgeDefinition } from '../types-CQCe_nBM.js';
1
+ import { R as RuntimeDependencies, j as RuntimeOptions, W as WorkflowBlueprint, b as NodeResult, C as ContextImplementation, N as NodeDefinition, E as EdgeDefinition } from '../types-CsTeXTiA.js';
2
2
  import { WorkflowState } from './state.js';
3
3
 
4
4
  /** Interface for the core runtime operations used by the traverser. */
@@ -6,7 +6,7 @@ interface IRuntime<TContext extends Record<string, any> = Record<string, any>, T
6
6
  options: RuntimeOptions<TDependencies>;
7
7
  registry: Record<string, any>;
8
8
  executeNode: (blueprint: WorkflowBlueprint, nodeId: string, state: WorkflowState<TContext>, allPredecessors?: Map<string, Set<string>>, functionRegistry?: Map<string, any>, executionId?: string, signal?: AbortSignal) => Promise<NodeResult>;
9
- determineNextNodes: (blueprint: WorkflowBlueprint, nodeId: string, result: NodeResult, context: ContextImplementation<TContext>) => Promise<{
9
+ determineNextNodes: (blueprint: WorkflowBlueprint, nodeId: string, result: NodeResult, context: ContextImplementation<TContext>, executionId?: string) => Promise<{
10
10
  node: NodeDefinition;
11
11
  edge: EdgeDefinition;
12
12
  }[]>;
@@ -1,4 +1,4 @@
1
- import { W as WorkflowBlueprint } from './types-CQCe_nBM.js';
1
+ import { W as WorkflowBlueprint } from './types-CsTeXTiA.js';
2
2
 
3
3
  /**
4
4
  * Sanitizes a raw workflow blueprint by removing extra properties
@@ -1,4 +1,4 @@
1
- import { n as ISerializer } from './types-CQCe_nBM.js';
1
+ import { n as ISerializer } from './types-CsTeXTiA.js';
2
2
 
3
3
  /**
4
4
  * A default serializer using standard JSON.
@@ -124,19 +124,27 @@ type ContextImplementation<T extends Record<string, any>> = ISyncContext<T> | IA
124
124
  /** The synchronous context interface for high-performance, in-memory state. */
125
125
  interface ISyncContext<TContext extends Record<string, any> = Record<string, any>> {
126
126
  readonly type: 'sync';
127
- get: <K extends keyof TContext>(key: K) => TContext[K] | undefined;
128
- set: <K extends keyof TContext>(key: K, value: TContext[K]) => void;
129
- has: <K extends keyof TContext>(key: K) => boolean;
130
- delete: <K extends keyof TContext>(key: K) => boolean;
127
+ get<K extends keyof TContext>(key: K): TContext[K] | undefined;
128
+ get(key: string): any | undefined;
129
+ set<K extends keyof TContext>(key: K, value: TContext[K]): void;
130
+ set(key: string, value: any): void;
131
+ has<K extends keyof TContext>(key: K): boolean;
132
+ has(key: string): boolean;
133
+ delete<K extends keyof TContext>(key: K): boolean;
134
+ delete(key: string): boolean;
131
135
  toJSON: () => Record<string, any>;
132
136
  }
133
137
  /** The asynchronous context interface for remote or distributed state. */
134
138
  interface IAsyncContext<TContext extends Record<string, any> = Record<string, any>> {
135
139
  readonly type: 'async';
136
- get: <K extends keyof TContext>(key: K) => Promise<TContext[K] | undefined>;
137
- set: <K extends keyof TContext>(key: K, value: TContext[K]) => Promise<void>;
138
- has: <K extends keyof TContext>(key: K) => Promise<boolean>;
139
- delete: <K extends keyof TContext>(key: K) => Promise<boolean>;
140
+ get<K extends keyof TContext>(key: K): Promise<TContext[K] | undefined>;
141
+ get(key: string): Promise<any | undefined>;
142
+ set<K extends keyof TContext>(key: K, value: TContext[K]): Promise<void>;
143
+ set(key: string, value: any): Promise<void>;
144
+ has<K extends keyof TContext>(key: K): Promise<boolean>;
145
+ has(key: string): Promise<boolean>;
146
+ delete<K extends keyof TContext>(key: K): Promise<boolean>;
147
+ delete(key: string): Promise<boolean>;
140
148
  toJSON: () => Promise<Record<string, any>>;
141
149
  }
142
150
  /** Generic for any set of dependencies. */
package/dist/types.d.ts CHANGED
@@ -1 +1 @@
1
- export { 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 } from './types-CQCe_nBM.js';
1
+ export { 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 } from './types-CsTeXTiA.js';
package/package.json CHANGED
@@ -1,52 +1,52 @@
1
1
  {
2
- "name": "flowcraft",
3
- "type": "module",
4
- "version": "2.1.1",
5
- "description": "A lightweight workflow framework",
6
- "license": "MIT",
7
- "homepage": "https://flowcraft.js.org",
8
- "repository": {
9
- "type": "git",
10
- "url": "https://github.com/gorango/flowcraft.git"
11
- },
12
- "bugs": "https://github.com/gorango/flowcraft/issues",
13
- "keywords": [
14
- "agentic-workflows",
15
- "ai-agent",
16
- "background-jobs",
17
- "dag",
18
- "data-pipelines",
19
- "declarative-workflows",
20
- "distributed-systems",
21
- "etl",
22
- "llm-orchestration",
23
- "orchestration",
24
- "rag",
25
- "state-machine",
26
- "workflow-engine"
27
- ],
28
- "exports": {
29
- ".": {
30
- "types": "./dist/index.d.ts",
31
- "import": "./dist/index.js"
32
- }
33
- },
34
- "files": [
35
- "dist"
36
- ],
37
- "scripts": {
38
- "dev": "tsup --watch",
39
- "build": "tsup",
40
- "typecheck": "tsc --noEmit",
41
- "test": "vitest run",
42
- "test:watch": "vitest",
43
- "test:coverage": "vitest run --coverage"
44
- },
45
- "devDependencies": {
46
- "@types/node": "^24.7.2",
47
- "@vitest/coverage-v8": "3.2.4",
48
- "tsup": "^8.5.0",
49
- "typescript": "^5.9.3",
50
- "vitest": "^3.2.4"
51
- }
52
- }
2
+ "name": "flowcraft",
3
+ "type": "module",
4
+ "version": "2.2.0",
5
+ "description": "A lightweight workflow framework",
6
+ "license": "MIT",
7
+ "homepage": "https://flowcraft.js.org",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/gorango/flowcraft.git"
11
+ },
12
+ "bugs": "https://github.com/gorango/flowcraft/issues",
13
+ "keywords": [
14
+ "agentic-workflows",
15
+ "ai-agent",
16
+ "background-jobs",
17
+ "dag",
18
+ "data-pipelines",
19
+ "declarative-workflows",
20
+ "distributed-systems",
21
+ "etl",
22
+ "llm-orchestration",
23
+ "orchestration",
24
+ "rag",
25
+ "state-machine",
26
+ "workflow-engine"
27
+ ],
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js"
32
+ }
33
+ },
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "devDependencies": {
38
+ "@types/node": "^24.8.0",
39
+ "@vitest/coverage-v8": "3.2.4",
40
+ "tsup": "^8.5.0",
41
+ "typescript": "^5.9.3",
42
+ "vitest": "^3.2.4"
43
+ },
44
+ "scripts": {
45
+ "dev": "tsup --watch",
46
+ "build": "tsup",
47
+ "typecheck": "tsc --noEmit",
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
50
+ "test:coverage": "vitest run --coverage"
51
+ }
52
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/runtime.ts"],"names":["nodeDef"],"mappings":"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","file":"chunk-3XVVR2SR.js","sourcesContent":["import type { BlueprintAnalysis } from '../analysis'\nimport { analyzeBlueprint } from '../analysis'\nimport { AsyncContextView } from '../context'\nimport { CancelledWorkflowError, FatalNodeExecutionError, NodeExecutionError } from '../errors'\nimport { PropertyEvaluator } from '../evaluator'\nimport { NullLogger } from '../logger'\nimport type { BaseNode } from '../node'\nimport { isNodeClass } from '../node'\nimport { sanitizeBlueprint } from '../sanitizer'\nimport { JsonSerializer } from '../serializer'\nimport type {\n\tContextImplementation,\n\tEdgeDefinition,\n\tIAsyncContext,\n\tIEvaluator,\n\tIEventBus,\n\tILogger,\n\tISerializer,\n\tISyncContext,\n\tMiddleware,\n\tNodeClass,\n\tNodeContext,\n\tNodeDefinition,\n\tNodeFunction,\n\tNodeResult,\n\tRuntimeOptions,\n\tWorkflowBlueprint,\n\tWorkflowResult,\n} from '../types'\nimport type { ExecutionStrategy } from './executors'\nimport { BuiltInNodeExecutor, ClassNodeExecutor, FunctionNodeExecutor } from './executors'\nimport { WorkflowState } from './state'\nimport { GraphTraverser } from './traverser'\nimport type { IRuntime } from './types'\n\nexport class FlowRuntime<TContext extends Record<string, any>, TDependencies extends Record<string, any>>\n\timplements IRuntime<TContext, TDependencies>\n{\n\tpublic registry: Record<string, NodeFunction | NodeClass | typeof BaseNode>\n\tprivate blueprints: Record<string, WorkflowBlueprint>\n\tprivate dependencies: TDependencies\n\tprivate logger: ILogger\n\tprivate eventBus: IEventBus\n\tprivate serializer: ISerializer\n\tprivate middleware: Middleware[]\n\tprivate evaluator: IEvaluator\n\tprivate analysisCache: WeakMap<WorkflowBlueprint, BlueprintAnalysis>\n\tpublic options: RuntimeOptions<TDependencies>\n\n\tconstructor(options: RuntimeOptions<TDependencies>) {\n\t\tthis.registry = options.registry || {}\n\t\tthis.blueprints = options.blueprints || {}\n\t\tthis.dependencies = options.dependencies || ({} as TDependencies)\n\t\tthis.logger = options.logger || new NullLogger()\n\t\tthis.eventBus = options.eventBus || { emit: () => {} }\n\t\tthis.serializer = options.serializer || new JsonSerializer()\n\t\tthis.middleware = options.middleware || []\n\t\tthis.evaluator = options.evaluator || new PropertyEvaluator()\n\t\tthis.analysisCache = new WeakMap()\n\t\tthis.options = options\n\t}\n\n\tasync run(\n\t\tblueprint: WorkflowBlueprint,\n\t\tinitialState: Partial<TContext> | string = {},\n\t\toptions?: {\n\t\t\tfunctionRegistry?: Map<string, any>\n\t\t\tstrict?: boolean\n\t\t\tsignal?: AbortSignal\n\t\t\tconcurrency?: number\n\t\t},\n\t): Promise<WorkflowResult<TContext>> {\n\t\tconst executionId = globalThis.crypto?.randomUUID()\n\t\tconst startTime = Date.now()\n\t\tconst contextData =\n\t\t\ttypeof initialState === 'string' ? (this.serializer.deserialize(initialState) as Partial<TContext>) : initialState\n\t\tblueprint = sanitizeBlueprint(blueprint)\n\t\tconst state = new WorkflowState<TContext>(contextData)\n\n\t\tthis.logger.info(`Starting workflow execution`, {\n\t\t\tblueprintId: blueprint.id,\n\t\t\texecutionId,\n\t\t})\n\n\t\ttry {\n\t\t\tawait this.eventBus.emit('workflow:start', {\n\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\texecutionId,\n\t\t\t})\n\t\t\tconst analysis =\n\t\t\t\tthis.analysisCache.get(blueprint) ??\n\t\t\t\t(() => {\n\t\t\t\t\tconst computed = analyzeBlueprint(blueprint)\n\t\t\t\t\tthis.analysisCache.set(blueprint, computed)\n\t\t\t\t\treturn computed\n\t\t\t\t})()\n\t\t\tif (options?.strict && !analysis.isDag) {\n\t\t\t\tthrow new Error(`Workflow '${blueprint.id}' failed strictness check: Cycles are not allowed.`)\n\t\t\t}\n\t\t\tif (!analysis.isDag) {\n\t\t\t\tthis.logger.warn(`Workflow contains cycles`, {\n\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst traverser = new GraphTraverser<TContext, TDependencies>(\n\t\t\t\tblueprint,\n\t\t\t\tthis,\n\t\t\t\tstate,\n\t\t\t\toptions?.functionRegistry,\n\t\t\t\texecutionId,\n\t\t\t\toptions?.signal,\n\t\t\t\toptions?.concurrency,\n\t\t\t)\n\t\t\tawait traverser.traverse()\n\t\t\tconst status = state.getStatus(traverser.getAllNodeIds(), traverser.getFallbackNodeIds())\n\t\t\tconst result = state.toResult(this.serializer)\n\t\t\tresult.status = status\n\t\t\tconst duration = Date.now() - startTime\n\t\t\tif (status === 'stalled') {\n\t\t\t\tawait this.eventBus.emit('workflow:stall', {\n\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t\texecutionId,\n\t\t\t\t\tremainingNodes: traverser.getAllNodeIds().size - state.getCompletedNodes().size,\n\t\t\t\t})\n\t\t\t}\n\t\t\tthis.logger.info(`Workflow execution completed`, {\n\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\texecutionId,\n\t\t\t\tstatus,\n\t\t\t\tduration,\n\t\t\t\terrors: result.errors?.length || 0,\n\t\t\t})\n\t\t\tawait this.eventBus.emit('workflow:finish', {\n\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\texecutionId,\n\t\t\t\tstatus,\n\t\t\t\terrors: result.errors,\n\t\t\t})\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tconst duration = Date.now() - startTime\n\t\t\tif (error instanceof DOMException ? error.name === 'AbortError' : error instanceof CancelledWorkflowError) {\n\t\t\t\tthis.logger.info(`Workflow execution cancelled`, {\n\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t\texecutionId,\n\t\t\t\t\tduration,\n\t\t\t\t})\n\t\t\t\tawait this.eventBus.emit('workflow:finish', {\n\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t\texecutionId,\n\t\t\t\t\tstatus: 'cancelled',\n\t\t\t\t\terror,\n\t\t\t\t})\n\t\t\t\treturn {\n\t\t\t\t\tcontext: {} as TContext,\n\t\t\t\t\tserializedContext: '{}',\n\t\t\t\t\tstatus: 'cancelled',\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.logger.error(`Workflow execution failed`, {\n\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\texecutionId,\n\t\t\t\tduration,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t})\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync executeNode(\n\t\tblueprint: WorkflowBlueprint,\n\t\tnodeId: string,\n\t\tstate: WorkflowState<TContext>,\n\t\tallPredecessors?: Map<string, Set<string>>,\n\t\tfunctionRegistry?: Map<string, any>,\n\t\texecutionId?: string,\n\t\tsignal?: AbortSignal,\n\t): Promise<NodeResult<any, any>> {\n\t\tconst nodeDef = blueprint.nodes.find((n) => n.id === nodeId)\n\t\tif (!nodeDef) {\n\t\t\tthrow new NodeExecutionError(\n\t\t\t\t`Node '${nodeId}' not found in blueprint.`,\n\t\t\t\tnodeId,\n\t\t\t\tblueprint.id,\n\t\t\t\tundefined,\n\t\t\t\texecutionId,\n\t\t\t)\n\t\t}\n\n\t\tconst contextImpl = state.getContext()\n\t\tconst asyncContext: IAsyncContext<TContext> =\n\t\t\tcontextImpl.type === 'sync'\n\t\t\t\t? new AsyncContextView(contextImpl as ISyncContext<TContext>)\n\t\t\t\t: (contextImpl as IAsyncContext<TContext>)\n\t\tconst nodeContext: NodeContext<TContext, TDependencies, any> = {\n\t\t\tcontext: asyncContext,\n\t\t\tinput: await this._resolveNodeInput(nodeDef, asyncContext, allPredecessors),\n\t\t\tparams: nodeDef.params || {},\n\t\t\tdependencies: { ...this.dependencies, logger: this.logger },\n\t\t\tsignal,\n\t\t}\n\n\t\tconst beforeHooks = this.middleware\n\t\t\t.map((m) => m.beforeNode)\n\t\t\t.filter((hook): hook is NonNullable<Middleware['beforeNode']> => !!hook)\n\t\tconst afterHooks = this.middleware\n\t\t\t.map((m) => m.afterNode)\n\t\t\t.filter((hook): hook is NonNullable<Middleware['afterNode']> => !!hook)\n\t\tconst aroundHooks = this.middleware\n\t\t\t.map((m) => m.aroundNode)\n\t\t\t.filter((hook): hook is NonNullable<Middleware['aroundNode']> => !!hook)\n\n\t\tconst executor = this.getExecutor(nodeDef, functionRegistry)\n\t\tconst coreExecution = async (): Promise<NodeResult> => {\n\t\t\tlet result: NodeResult | undefined\n\t\t\tlet error: Error | undefined\n\t\t\ttry {\n\t\t\t\tfor (const hook of beforeHooks) await hook(nodeContext.context, nodeId)\n\t\t\t\tresult = await this.executeWithFallback(\n\t\t\t\t\tblueprint,\n\t\t\t\t\tnodeDef,\n\t\t\t\t\tnodeContext,\n\t\t\t\t\texecutor,\n\t\t\t\t\texecutionId,\n\t\t\t\t\tsignal,\n\t\t\t\t\tstate,\n\t\t\t\t\tfunctionRegistry,\n\t\t\t\t)\n\t\t\t\treturn result\n\t\t\t} catch (e: any) {\n\t\t\t\terror = e\n\t\t\t\tthrow e\n\t\t\t} finally {\n\t\t\t\tfor (const hook of afterHooks) await hook(nodeContext.context, nodeId, result, error)\n\t\t\t}\n\t\t}\n\n\t\tlet executionChain: () => Promise<NodeResult> = coreExecution\n\t\tfor (let i = aroundHooks.length - 1; i >= 0; i--) {\n\t\t\tconst hook = aroundHooks[i]\n\t\t\tconst next = executionChain\n\t\t\texecutionChain = () => hook(nodeContext.context, nodeId, next)\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.eventBus.emit('node:start', {\n\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\tnodeId,\n\t\t\t\texecutionId,\n\t\t\t})\n\t\t\tconst result = await executionChain()\n\t\t\tawait this.eventBus.emit('node:finish', {\n\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\tnodeId,\n\t\t\t\tresult,\n\t\t\t\texecutionId,\n\t\t\t})\n\t\t\treturn result\n\t\t} catch (error: any) {\n\t\t\tawait this.eventBus.emit('node:error', {\n\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\tnodeId,\n\t\t\t\terror,\n\t\t\t\texecutionId,\n\t\t\t})\n\t\t\tif (error instanceof DOMException && error.name === 'AbortError') {\n\t\t\t\tthrow new CancelledWorkflowError('Workflow cancelled')\n\t\t\t}\n\t\t\tthrow error instanceof NodeExecutionError\n\t\t\t\t? error\n\t\t\t\t: new NodeExecutionError(`Node '${nodeId}' failed execution.`, nodeId, blueprint.id, error, executionId)\n\t\t}\n\t}\n\n\tprivate getExecutor(nodeDef: NodeDefinition, functionRegistry?: Map<string, any>): ExecutionStrategy {\n\t\tif (nodeDef.uses.startsWith('batch-') || nodeDef.uses.startsWith('loop-') || nodeDef.uses === 'subflow') {\n\t\t\treturn new BuiltInNodeExecutor((nodeDef, context) => this._executeBuiltInNode(nodeDef, context))\n\t\t}\n\t\tconst implementation = functionRegistry?.get(nodeDef.uses) || this.registry[nodeDef.uses]\n\t\tif (!implementation) {\n\t\t\tthrow new FatalNodeExecutionError(\n\t\t\t\t`Implementation for '${nodeDef.uses}' not found for node '${nodeDef.id}'.`,\n\t\t\t\tnodeDef.id,\n\t\t\t\t'',\n\t\t\t)\n\t\t}\n\t\tconst maxRetries = nodeDef.config?.maxRetries ?? 1\n\t\treturn isNodeClass(implementation)\n\t\t\t? new ClassNodeExecutor(implementation, maxRetries, this.eventBus)\n\t\t\t: new FunctionNodeExecutor(implementation, maxRetries, this.eventBus)\n\t}\n\n\tprivate async executeWithFallback(\n\t\tblueprint: WorkflowBlueprint,\n\t\tnodeDef: NodeDefinition,\n\t\tcontext: NodeContext<TContext, TDependencies, any>,\n\t\texecutor: ExecutionStrategy,\n\t\texecutionId?: string,\n\t\tsignal?: AbortSignal,\n\t\tstate?: WorkflowState<TContext>,\n\t\tfunctionRegistry?: Map<string, any>,\n\t): Promise<NodeResult<any, any>> {\n\t\ttry {\n\t\t\treturn await executor.execute(nodeDef, context, executionId, signal)\n\t\t} catch (error) {\n\t\t\tconst isFatal =\n\t\t\t\terror instanceof FatalNodeExecutionError ||\n\t\t\t\t(error instanceof NodeExecutionError && error.originalError instanceof FatalNodeExecutionError)\n\t\t\tif (isFatal) throw error\n\t\t\tconst fallbackNodeId = nodeDef.config?.fallback\n\t\t\tif (fallbackNodeId && state) {\n\t\t\t\tcontext.dependencies.logger.warn(`Executing fallback for node`, {\n\t\t\t\t\tnodeId: nodeDef.id,\n\t\t\t\t\tfallbackNodeId,\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\texecutionId,\n\t\t\t\t})\n\t\t\t\tawait this.eventBus.emit('node:fallback', {\n\t\t\t\t\tblueprintId: blueprint.id,\n\t\t\t\t\tnodeId: nodeDef.id,\n\t\t\t\t\texecutionId,\n\t\t\t\t\tfallback: fallbackNodeId,\n\t\t\t\t})\n\t\t\t\tconst fallbackNode = blueprint.nodes.find((n: NodeDefinition) => n.id === fallbackNodeId)\n\t\t\t\tif (!fallbackNode) {\n\t\t\t\t\tthrow new NodeExecutionError(\n\t\t\t\t\t\t`Fallback node '${fallbackNodeId}' not found in blueprint.`,\n\t\t\t\t\t\tnodeDef.id,\n\t\t\t\t\t\tblueprint.id,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\texecutionId,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tconst fallbackExecutor = this.getExecutor(fallbackNode, functionRegistry)\n\t\t\t\tconst fallbackResult = await fallbackExecutor.execute(fallbackNode, context, executionId, signal)\n\t\t\t\tstate.markFallbackExecuted()\n\t\t\t\tstate.addCompletedNode(fallbackNodeId, fallbackResult.output)\n\t\t\t\tcontext.dependencies.logger.info(`Fallback execution completed`, {\n\t\t\t\t\tnodeId: nodeDef.id,\n\t\t\t\t\tfallbackNodeId,\n\t\t\t\t\texecutionId,\n\t\t\t\t})\n\t\t\t\treturn { ...fallbackResult, _fallbackExecuted: true }\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync determineNextNodes(\n\t\tblueprint: WorkflowBlueprint,\n\t\tnodeId: string,\n\t\tresult: NodeResult<any, any>,\n\t\tcontext: ContextImplementation<TContext>,\n\t): Promise<{ node: NodeDefinition; edge: EdgeDefinition }[]> {\n\t\tconst outgoingEdges = blueprint.edges.filter((edge) => edge.source === nodeId)\n\t\tconst matched: { node: NodeDefinition; edge: EdgeDefinition }[] = []\n\t\tconst evaluateEdge = async (edge: EdgeDefinition): Promise<boolean> => {\n\t\t\tif (!edge.condition) return true\n\t\t\tconst contextData = context.type === 'sync' ? context.toJSON() : await context.toJSON()\n\t\t\treturn !!this.evaluator.evaluate(edge.condition, {\n\t\t\t\t...contextData,\n\t\t\t\tresult,\n\t\t\t})\n\t\t}\n\t\tif (result.action) {\n\t\t\tconst actionEdges = outgoingEdges.filter((edge) => edge.action === result.action)\n\t\t\tfor (const edge of actionEdges) {\n\t\t\t\tif (await evaluateEdge(edge)) {\n\t\t\t\t\tconst targetNode = blueprint.nodes.find((n) => n.id === edge.target)\n\t\t\t\t\tif (targetNode) matched.push({ node: targetNode, edge })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (matched.length === 0) {\n\t\t\tconst defaultEdges = outgoingEdges.filter((edge) => !edge.action)\n\t\t\tfor (const edge of defaultEdges) {\n\t\t\t\tif (await evaluateEdge(edge)) {\n\t\t\t\t\tconst targetNode = blueprint.nodes.find((n) => n.id === edge.target)\n\t\t\t\t\tif (targetNode) matched.push({ node: targetNode, edge })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.logger.debug(`Determined next nodes for ${nodeId}`, {\n\t\t\tmatchedNodes: matched.map((m) => m.node.id),\n\t\t\taction: result.action,\n\t\t})\n\t\treturn matched\n\t}\n\n\tpublic async applyEdgeTransform(\n\t\tedge: EdgeDefinition,\n\t\tsourceResult: NodeResult<any, any>,\n\t\ttargetNode: NodeDefinition,\n\t\tcontext: ContextImplementation<TContext>,\n\t\tallPredecessors?: Map<string, Set<string>>,\n\t): Promise<void> {\n\t\tconst asyncContext = context.type === 'sync' ? new AsyncContextView(context) : context\n\t\tconst finalInput = edge.transform\n\t\t\t? this.evaluator.evaluate(edge.transform, {\n\t\t\t\t\tinput: sourceResult.output,\n\t\t\t\t\tcontext: await asyncContext.toJSON(),\n\t\t\t\t})\n\t\t\t: sourceResult.output\n\t\tconst inputKey = `${targetNode.id}_input`\n\t\tawait asyncContext.set(inputKey as any, finalInput)\n\t\tif (targetNode.config?.joinStrategy === 'any') {\n\t\t\ttargetNode.inputs = inputKey\n\t\t} else if (!targetNode.inputs) {\n\t\t\tconst predecessors = allPredecessors?.get(targetNode.id)\n\t\t\tif (!predecessors || predecessors.size === 1) {\n\t\t\t\ttargetNode.inputs = inputKey\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async _resolveNodeInput(\n\t\tnodeDef: NodeDefinition,\n\t\tcontext: IAsyncContext<TContext>,\n\t\tallPredecessors?: Map<string, Set<string>>,\n\t): Promise<any> {\n\t\tif (nodeDef.inputs) {\n\t\t\tif (typeof nodeDef.inputs === 'string') return await context.get(nodeDef.inputs as any)\n\t\t\tif (typeof nodeDef.inputs === 'object') {\n\t\t\t\tconst input: Record<string, any> = {}\n\t\t\t\tfor (const key in nodeDef.inputs) {\n\t\t\t\t\tconst contextKey = nodeDef.inputs[key]\n\t\t\t\t\tinput[key] = await context.get(contextKey as any)\n\t\t\t\t}\n\t\t\t\treturn input\n\t\t\t}\n\t\t}\n\t\tif (allPredecessors) {\n\t\t\tconst predecessors = allPredecessors.get(nodeDef.id)\n\t\t\tif (predecessors && predecessors.size === 1) {\n\t\t\t\tconst singlePredecessorId = predecessors.values().next().value\n\t\t\t\treturn await context.get(singlePredecessorId as any)\n\t\t\t}\n\t\t}\n\t\treturn undefined\n\t}\n\n\tprotected async _executeBuiltInNode(\n\t\tnodeDef: NodeDefinition,\n\t\tcontextImpl: ContextImplementation<TContext>,\n\t): Promise<NodeResult<any, any>> {\n\t\tconst context = contextImpl.type === 'sync' ? new AsyncContextView(contextImpl) : contextImpl\n\t\tconst { params = {}, id, inputs } = nodeDef\n\t\tswitch (nodeDef.uses) {\n\t\t\tcase 'batch-scatter': {\n\t\t\t\tconst inputArray = (await context.get(inputs as any)) || []\n\t\t\t\tif (!Array.isArray(inputArray))\n\t\t\t\t\tthrow new FatalNodeExecutionError(`Input for batch-scatter node '${id}' must be an array.`, id, '')\n\t\t\t\tconst batchId = globalThis.crypto.randomUUID()\n\t\t\t\tconst dynamicNodes: NodeDefinition[] = []\n\t\t\t\tfor (let i = 0; i < inputArray.length; i++) {\n\t\t\t\t\tconst item = inputArray[i]\n\t\t\t\t\tconst itemInputKey = `${id}_${batchId}_item_${i}`\n\t\t\t\t\tawait context.set(itemInputKey as any, item)\n\t\t\t\t\tdynamicNodes.push({\n\t\t\t\t\t\tid: `${params.workerUsesKey}_${batchId}_${i}`,\n\t\t\t\t\t\tuses: params.workerUsesKey,\n\t\t\t\t\t\tinputs: itemInputKey,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconst gatherNodeId = params.gatherNodeId\n\t\t\t\treturn { dynamicNodes, output: { gatherNodeId } }\n\t\t\t}\n\t\t\tcase 'batch-gather': {\n\t\t\t\treturn { output: {} }\n\t\t\t}\n\t\t\tcase 'loop-controller': {\n\t\t\t\tconst contextData = await context.toJSON()\n\t\t\t\tconst shouldContinue = !!this.evaluator.evaluate(params.condition, contextData)\n\t\t\t\treturn { action: shouldContinue ? 'continue' : 'break' }\n\t\t\t}\n\t\t\tcase 'subflow': {\n\t\t\t\tconst { blueprintId, inputs: inputMapping, outputs: outputMapping } = params\n\t\t\t\tif (!blueprintId)\n\t\t\t\t\tthrow new FatalNodeExecutionError(`Subflow node '${id}' is missing the 'blueprintId' parameter.`, id, '')\n\n\t\t\t\tconst subBlueprint = this.blueprints[blueprintId]\n\t\t\t\tif (!subBlueprint)\n\t\t\t\t\tthrow new FatalNodeExecutionError(\n\t\t\t\t\t\t`Sub-blueprint with ID '${blueprintId}' not found in runtime registry.`,\n\t\t\t\t\t\tid,\n\t\t\t\t\t\t'',\n\t\t\t\t\t)\n\n\t\t\t\tconst subflowInitialContext: Record<string, any> = {}\n\n\t\t\t\tif (inputMapping) {\n\t\t\t\t\tfor (const [targetKey, sourceKey] of Object.entries(inputMapping)) {\n\t\t\t\t\t\tif (await context.has(sourceKey as any)) {\n\t\t\t\t\t\t\tsubflowInitialContext[targetKey] = await context.get(sourceKey as any)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst subflowResult = await this.run(subBlueprint, subflowInitialContext as Partial<TContext>)\n\n\t\t\t\tif (subflowResult.status !== 'completed')\n\t\t\t\t\tthrow new NodeExecutionError(\n\t\t\t\t\t\t`Sub-workflow '${blueprintId}' did not complete successfully. Status: ${subflowResult.status}`,\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tsubBlueprint.id,\n\t\t\t\t\t)\n\n\t\t\t\tif (outputMapping) {\n\t\t\t\t\tfor (const [parentKey, subKey] of Object.entries(outputMapping)) {\n\t\t\t\t\t\tconst subflowFinalContext = subflowResult.context as Record<string, any>\n\t\t\t\t\t\tif (Object.hasOwn(subflowFinalContext, subKey as string)) {\n\t\t\t\t\t\t\tawait context.set(parentKey as any, subflowFinalContext[subKey as string])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn { output: subflowResult.context }\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new FatalNodeExecutionError(`Unknown built-in node type: '${nodeDef.uses}'`, id, '')\n\t\t}\n\t}\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/flow.ts"],"names":[],"mappings":"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","file":"chunk-4A627Q6L.js","sourcesContent":["import { isNodeClass } from './node'\nimport type { EdgeDefinition, NodeClass, NodeDefinition, NodeFunction, WorkflowBlueprint } from './types'\n\n/**\n * Generates a deterministic hash for a function based on its source code.\n */\nfunction _hashFunction(fn: NodeFunction<any, any, any, any, any> | NodeClass<any, any, any, any, any>): string {\n\tconst source = fn.toString()\n\tlet hash = 0\n\tfor (let i = 0; i < source.length; i++) {\n\t\tconst char = source.charCodeAt(i)\n\t\thash = (hash << 5) - hash + char\n\t\thash = hash & hash // Convert to 32-bit integer\n\t}\n\treturn Math.abs(hash).toString(16)\n}\n\n/**\n * A fluent API for programmatically constructing a WorkflowBlueprint.\n */\nexport class Flow<\n\tTContext extends Record<string, any> = Record<string, any>,\n\tTDependencies extends Record<string, any> = Record<string, any>,\n> {\n\tprivate blueprint: Partial<WorkflowBlueprint>\n\tprivate functionRegistry: Map<string, NodeFunction | NodeClass>\n\tprivate loopControllerIds: Map<string, string>\n\tprivate loopDefinitions: Array<{\n\t\tid: string\n\t\tstartNodeId: string\n\t\tendNodeId: string\n\t}>\n\n\tconstructor(id: string) {\n\t\tthis.blueprint = { id, nodes: [], edges: [] }\n\t\tthis.functionRegistry = new Map()\n\t\tthis.loopControllerIds = new Map()\n\t\tthis.loopDefinitions = []\n\t}\n\n\tnode<TInput = any, TOutput = any, TAction extends string = string>(\n\t\tid: string,\n\t\timplementation:\n\t\t\t| NodeFunction<TContext, TDependencies, TInput, TOutput, TAction>\n\t\t\t| NodeClass<TContext, TDependencies, TInput, TOutput, TAction>,\n\t\toptions?: Omit<NodeDefinition, 'id' | 'uses'>,\n\t): this {\n\t\tlet usesKey: string\n\n\t\tif (isNodeClass(implementation)) {\n\t\t\tusesKey =\n\t\t\t\timplementation.name && implementation.name !== 'BaseNode'\n\t\t\t\t\t? implementation.name\n\t\t\t\t\t: `class_${_hashFunction(implementation)}`\n\t\t\tthis.functionRegistry.set(usesKey, implementation)\n\t\t} else {\n\t\t\tusesKey = `fn_${_hashFunction(implementation)}`\n\t\t\tthis.functionRegistry.set(usesKey, implementation as unknown as NodeFunction)\n\t\t}\n\n\t\tconst nodeDef: NodeDefinition = { id, uses: usesKey, ...options }\n\t\tthis.blueprint.nodes?.push(nodeDef)\n\t\treturn this\n\t}\n\n\tedge(source: string, target: string, options?: Omit<EdgeDefinition, 'source' | 'target'>): this {\n\t\tconst edgeDef: EdgeDefinition = { source, target, ...options }\n\t\tthis.blueprint.edges?.push(edgeDef)\n\t\treturn this\n\t}\n\n\t/**\n\t * Creates a batch processing pattern.\n\t * It takes an input array, runs a worker node on each item in parallel, and gathers the results.\n\t * @param id The base ID for this batch operation.\n\t * @param worker The node implementation to run on each item.\n\t * @param options Configuration for the batch operation.\n\t * @param options.inputKey The key in the context that holds the input array for the batch.\n\t * @param options.outputKey The key in the context where the array of results will be stored.\n\t * @returns The Flow instance for chaining.\n\t */\n\tbatch<TInput = any, TOutput = any, TAction extends string = string>(\n\t\tid: string,\n\t\tworker:\n\t\t\t| NodeFunction<TContext, TDependencies, TInput, TOutput, TAction>\n\t\t\t| NodeClass<TContext, TDependencies, TInput, TOutput, TAction>,\n\t\toptions: {\n\t\t\t/** The key in the context that holds the input array for the batch. */\n\t\t\tinputKey: keyof TContext\n\t\t\t/** The key in the context where the array of results will be stored. */\n\t\t\toutputKey: keyof TContext\n\t\t},\n\t): this {\n\t\tconst { inputKey, outputKey } = options\n\t\tconst scatterId = `${id}_scatter`\n\t\tconst gatherId = `${id}_gather`\n\n\t\t// register worker implementation under a unique key.\n\t\tlet workerUsesKey: string\n\t\tif (isNodeClass(worker)) {\n\t\t\tworkerUsesKey =\n\t\t\t\tworker.name && worker.name !== 'BaseNode' ? worker.name : `class_batch_worker_${_hashFunction(worker)}`\n\t\t\tthis.functionRegistry.set(workerUsesKey, worker)\n\t\t} else {\n\t\t\tworkerUsesKey = `fn_batch_worker_${_hashFunction(worker)}`\n\t\t\tthis.functionRegistry.set(workerUsesKey, worker as unknown as NodeFunction)\n\t\t}\n\n\t\t// scatter node: takes an array and dynamically schedules worker nodes\n\t\tthis.blueprint.nodes?.push({\n\t\t\tid: scatterId,\n\t\t\tuses: 'batch-scatter', // built-in\n\t\t\tinputs: inputKey as string,\n\t\t\tparams: { workerUsesKey, outputKey: outputKey as string, gatherNodeId: gatherId },\n\t\t})\n\n\t\t// gather node: waits for all workers to finish and collects the results\n\t\tthis.blueprint.nodes?.push({\n\t\t\tid: gatherId,\n\t\t\tuses: 'batch-gather', // built-in\n\t\t\tparams: { outputKey },\n\t\t\tconfig: { joinStrategy: 'all' }, // important: must wait for all scattered jobs\n\t\t})\n\n\t\t// edge to connect scatter and gather nodes. orchestrator will manage dynamic workers\n\t\tthis.edge(scatterId, gatherId)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Creates a loop pattern in the workflow graph.\n\t * @param id A unique identifier for the loop construct.\n\t * @param options Defines the start, end, and continuation condition of the loop.\n\t * @param options.startNodeId The ID of the first node inside the loop body.\n\t * @param options.endNodeId The ID of the last node inside the loop body.\n\t * @param options.condition An expression that, if true, causes the loop to run again.\n\t */\n\tloop(\n\t\tid: string,\n\t\toptions: {\n\t\t\t/** The ID of the first node inside the loop body. */\n\t\t\tstartNodeId: string\n\t\t\t/** The ID of the last node inside the loop body. */\n\t\t\tendNodeId: string\n\t\t\t/** An expression that, if true, causes the loop to run again. */\n\t\t\tcondition: string\n\t\t},\n\t): this {\n\t\tconst { startNodeId, endNodeId, condition } = options\n\t\tconst controllerId = `${id}-loop`\n\n\t\tthis.loopControllerIds.set(id, controllerId)\n\n\t\tthis.loopDefinitions.push({ id, startNodeId, endNodeId })\n\n\t\t// controller node: evaluates the loop condition\n\t\tthis.blueprint.nodes?.push({\n\t\t\tid: controllerId,\n\t\t\tuses: 'loop-controller', // built-in\n\t\t\tparams: { condition },\n\t\t\tconfig: { joinStrategy: 'any' }, // to allow re-execution on each loop iteration\n\t\t})\n\n\t\tthis.edge(endNodeId, controllerId)\n\n\t\tthis.edge(controllerId, startNodeId, {\n\t\t\taction: 'continue',\n\t\t\ttransform: `context.${endNodeId}`, // pass the end node's value to the start node\n\t\t})\n\n\t\treturn this\n\t}\n\n\tgetLoopControllerId(id: string): string {\n\t\tconst controllerId = this.loopControllerIds.get(id)\n\t\tif (!controllerId) {\n\t\t\tthrow new Error(`Loop with id '${id}' not found. Ensure you have defined it using the .loop() method.`)\n\t\t}\n\t\treturn controllerId\n\t}\n\n\ttoBlueprint(): WorkflowBlueprint {\n\t\tif (!this.blueprint.nodes || this.blueprint.nodes.length === 0) {\n\t\t\tthrow new Error('Cannot build a blueprint with no nodes.')\n\t\t}\n\n\t\tfor (const loopDef of this.loopDefinitions) {\n\t\t\tconst startNode = this.blueprint.nodes?.find((n) => n.id === loopDef.startNodeId)\n\t\t\tconst endNode = this.blueprint.nodes?.find((n) => n.id === loopDef.endNodeId)\n\n\t\t\tif (!startNode) {\n\t\t\t\tthrow new Error(`Loop '${loopDef.id}' references non-existent start node '${loopDef.startNodeId}'.`)\n\t\t\t}\n\t\t\tif (!endNode) {\n\t\t\t\tthrow new Error(`Loop '${loopDef.id}' references non-existent end node '${loopDef.endNodeId}'.`)\n\t\t\t}\n\n\t\t\tstartNode.config = { ...startNode.config, joinStrategy: 'any' }\n\t\t\tendNode.config = { ...endNode.config, joinStrategy: 'any' }\n\t\t}\n\n\t\treturn this.blueprint as WorkflowBlueprint\n\t}\n\n\tgetFunctionRegistry() {\n\t\treturn this.functionRegistry\n\t}\n}\n\n/**\n * Helper function to create a new Flow builder instance.\n */\nexport function createFlow<\n\tTContext extends Record<string, any> = Record<string, any>,\n\tTDependencies extends Record<string, any> = Record<string, any>,\n>(id: string): Flow<TContext, TDependencies> {\n\treturn new Flow(id)\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/state.ts"],"names":[],"mappings":";;;AAGO,IAAM,gBAAN,MAA0D;AAAA,EACxD,eAAA,uBAAsB,GAAA,EAAY;AAAA,EAClC,SAA0B,EAAC;AAAA,EAC3B,mBAAA,GAAsB,KAAA;AAAA,EACtB,OAAA;AAAA,EAER,YAAY,WAAA,EAAgC;AAC3C,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,OAAA,CAAkB,WAAW,CAAA;AAAA,EACjD;AAAA,EAEA,gBAAA,CAAiB,QAAgB,MAAA,EAAa;AAC7C,IAAA,IAAA,CAAK,eAAA,CAAgB,IAAI,MAAM,CAAA;AAC/B,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,MAAA,EAA0B,MAAM,CAAA;AAAA,EAClD;AAAA,EAEA,QAAA,CAAS,QAAgB,KAAA,EAAc;AACtC,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK;AAAA,MAChB,MAAA;AAAA,MACA,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,aAAA,EAAe,KAAA;AAAA,MACf,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAClC,OAAO,KAAA,CAAM;AAAA,KACb,CAAA;AAAA,EACF;AAAA,EAEA,WAAW,MAAA,EAAgB;AAC1B,IAAA,IAAA,CAAK,MAAA,GAAS,KAAK,MAAA,CAAO,MAAA,CAAO,CAAC,GAAA,KAAQ,GAAA,CAAI,WAAW,MAAM,CAAA;AAAA,EAChE;AAAA,EAEA,oBAAA,GAAuB;AACtB,IAAA,IAAA,CAAK,mBAAA,GAAsB,IAAA;AAAA,EAC5B;AAAA,EAEA,UAAA,GAA8C;AAC7C,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACb;AAAA,EAEA,iBAAA,GAAiC;AAChC,IAAA,OAAO,IAAI,GAAA,CAAI,IAAA,CAAK,eAAe,CAAA;AAAA,EACpC;AAAA,EAEA,SAAA,GAA6B;AAC5B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACb;AAAA,EAEA,sBAAA,GAAkC;AACjC,IAAA,OAAO,IAAA,CAAK,mBAAA;AAAA,EACb;AAAA,EAEA,SAAA,CAAU,YAAyB,gBAAA,EAAyD;AAC3F,IAAA,IAAI,IAAA,CAAK,qBAAqB,OAAO,WAAA;AACrC,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,OAAO,QAAA;AAEnC,IAAA,OAAO,IAAA,CAAK,eAAA,CAAgB,IAAA,GAAO,UAAA,CAAW,OAAO,SAAA,GAAY,WAAA;AAAA,EAClE;AAAA,EAEA,SAAS,UAAA,EAAmD;AAC3D,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO;AACxC,IAAA,OAAO;AAAA,MACN,OAAA,EAAS,WAAA;AAAA,MACT,iBAAA,EAAmB,UAAA,CAAW,SAAA,CAAU,WAAW,CAAA;AAAA,MACnD,MAAA,EAAQ,KAAK,SAAA,iBAAU,IAAI,KAAI,kBAAG,IAAI,KAAK,CAAA;AAAA,MAC3C,QAAQ,IAAA,CAAK,MAAA,CAAO,MAAA,GAAS,CAAA,GAAI,KAAK,MAAA,GAAS;AAAA,KAChD;AAAA,EACD;AACD","file":"chunk-CSZ6EOWG.js","sourcesContent":["import { Context } from '../context'\nimport type { ContextImplementation, ISerializer, WorkflowError, WorkflowResult } from '../types'\n\nexport class WorkflowState<TContext extends Record<string, any>> {\n\tprivate _completedNodes = new Set<string>()\n\tprivate errors: WorkflowError[] = []\n\tprivate anyFallbackExecuted = false\n\tprivate context: ContextImplementation<TContext>\n\n\tconstructor(initialData: Partial<TContext>) {\n\t\tthis.context = new Context<TContext>(initialData)\n\t}\n\n\taddCompletedNode(nodeId: string, output: any) {\n\t\tthis._completedNodes.add(nodeId)\n\t\tthis.context.set(nodeId as keyof TContext, output)\n\t}\n\n\taddError(nodeId: string, error: Error) {\n\t\tthis.errors.push({\n\t\t\tnodeId,\n\t\t\tmessage: error.message,\n\t\t\toriginalError: error,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tstack: error.stack,\n\t\t})\n\t}\n\n\tclearError(nodeId: string) {\n\t\tthis.errors = this.errors.filter((err) => err.nodeId !== nodeId)\n\t}\n\n\tmarkFallbackExecuted() {\n\t\tthis.anyFallbackExecuted = true\n\t}\n\n\tgetContext(): ContextImplementation<TContext> {\n\t\treturn this.context\n\t}\n\n\tgetCompletedNodes(): Set<string> {\n\t\treturn new Set(this._completedNodes)\n\t}\n\n\tgetErrors(): WorkflowError[] {\n\t\treturn this.errors\n\t}\n\n\tgetAnyFallbackExecuted(): boolean {\n\t\treturn this.anyFallbackExecuted\n\t}\n\n\tgetStatus(allNodeIds: Set<string>, _fallbackNodeIds: Set<string>): WorkflowResult['status'] {\n\t\tif (this.anyFallbackExecuted) return 'completed'\n\t\tif (this.errors.length > 0) return 'failed'\n\t\t// const _remainingNodes = [...allNodeIds].filter((id) => !this._completedNodes.has(id) && !fallbackNodeIds.has(id))\n\t\treturn this._completedNodes.size < allNodeIds.size ? 'stalled' : 'completed'\n\t}\n\n\ttoResult(serializer: ISerializer): WorkflowResult<TContext> {\n\t\tconst contextJSON = this.context.toJSON() as TContext\n\t\treturn {\n\t\t\tcontext: contextJSON,\n\t\t\tserializedContext: serializer.serialize(contextJSON),\n\t\t\tstatus: this.getStatus(new Set(), new Set()),\n\t\t\terrors: this.errors.length > 0 ? this.errors : undefined,\n\t\t}\n\t}\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/analysis.ts"],"names":[],"mappings":"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","file":"chunk-HN72TZY5.js","sourcesContent":["import type { WorkflowBlueprint } from './types'\n\n/**\n * A list of cycles found in the graph. Each cycle is an array of node IDs.\n */\nexport type Cycles = string[][]\n\n/**\n * Analysis result for a workflow blueprint\n */\nexport interface BlueprintAnalysis {\n\t/** Cycles found in the graph */\n\tcycles: Cycles\n\t/** Node IDs that have no incoming edges (start nodes) */\n\tstartNodeIds: string[]\n\t/** Node IDs that have no outgoing edges (terminal nodes) */\n\tterminalNodeIds: string[]\n\t/** Total number of nodes */\n\tnodeCount: number\n\t/** Total number of edges */\n\tedgeCount: number\n\t/** Whether the graph is a valid DAG (no cycles) */\n\tisDag: boolean\n}\n\n/**\n * Analyzes a workflow blueprint to detect cycles.\n * @param blueprint The WorkflowBlueprint object containing nodes and edges.\n * @returns An array of cycles found. Each cycle is represented as an array of node IDs.\n */\nexport function checkForCycles(blueprint: WorkflowBlueprint): Cycles {\n\tconst cycles: Cycles = []\n\tif (!blueprint || !blueprint.nodes || blueprint.nodes.length === 0) {\n\t\treturn cycles\n\t}\n\n\tconst allNodeIds = blueprint.nodes.map((node) => node.id)\n\tconst adj = new Map<string, string[]>()\n\tfor (const id of allNodeIds) {\n\t\tadj.set(id, [])\n\t}\n\tfor (const edge of blueprint.edges) {\n\t\tadj.get(edge.source)?.push(edge.target)\n\t}\n\n\tconst visited = new Set<string>()\n\tconst recursionStack = new Set<string>()\n\n\tfunction detectCycleUtil(nodeId: string, path: string[]) {\n\t\tvisited.add(nodeId)\n\t\trecursionStack.add(nodeId)\n\t\tpath.push(nodeId)\n\n\t\tconst neighbors = adj.get(nodeId) || []\n\t\tfor (const neighbor of neighbors) {\n\t\t\tif (recursionStack.has(neighbor)) {\n\t\t\t\tconst cycleStartIndex = path.indexOf(neighbor)\n\t\t\t\tconst cycle = path.slice(cycleStartIndex)\n\t\t\t\tcycles.push([...cycle, neighbor])\n\t\t\t} else if (!visited.has(neighbor)) {\n\t\t\t\tdetectCycleUtil(neighbor, path)\n\t\t\t}\n\t\t}\n\n\t\trecursionStack.delete(nodeId)\n\t\tpath.pop()\n\t}\n\n\tfor (const nodeId of allNodeIds) {\n\t\tif (!visited.has(nodeId)) {\n\t\t\tdetectCycleUtil(nodeId, [])\n\t\t}\n\t}\n\n\treturn cycles\n}\n\n/**\n * Generates Mermaid diagram syntax from a WorkflowBlueprint\n * @param blueprint The WorkflowBlueprint object containing nodes and edges\n * @returns Mermaid syntax string for the flowchart\n */\nexport function generateMermaid(blueprint: WorkflowBlueprint): string {\n\tif (!blueprint || !blueprint.nodes || blueprint.nodes.length === 0) {\n\t\treturn 'flowchart TD\\n empty[Empty Blueprint]'\n\t}\n\n\tlet mermaid = 'flowchart TD\\n'\n\n\tfor (const node of blueprint.nodes) {\n\t\t// Using backticks and characters like <br/> for newlines in Mermaid labels\n\t\tconst paramsString = node.params ? `<br/>params: ${JSON.stringify(node.params)}` : ''\n\t\tconst nodeLabel = `${node.id}${paramsString}`\n\t\tmermaid += ` ${node.id}[\"${nodeLabel}\"]\\n`\n\t}\n\n\tfor (const edge of blueprint.edges || []) {\n\t\tconst labelParts: string[] = []\n\n\t\tif (edge.action) {\n\t\t\tlabelParts.push(edge.action)\n\t\t}\n\t\tif (edge.condition) {\n\t\t\tlabelParts.push(edge.condition)\n\t\t}\n\t\tif (edge.transform) {\n\t\t\tlabelParts.push(edge.transform)\n\t\t}\n\n\t\tif (labelParts.length > 0) {\n\t\t\tconst edgeLabel = labelParts.join(' | ')\n\t\t\tmermaid += ` ${edge.source} -- \"${edgeLabel}\" --> ${edge.target}\\n`\n\t\t} else {\n\t\t\tmermaid += ` ${edge.source} --> ${edge.target}\\n`\n\t\t}\n\t}\n\n\treturn mermaid\n}\n\n/**\n * Analyzes a workflow blueprint and returns comprehensive analysis\n * @param blueprint The WorkflowBlueprint object containing nodes and edges\n * @returns Analysis result with cycles, start nodes, terminal nodes, and other metrics\n */\nexport function analyzeBlueprint(blueprint: WorkflowBlueprint): BlueprintAnalysis {\n\tif (!blueprint || !blueprint.nodes || blueprint.nodes.length === 0) {\n\t\treturn {\n\t\t\tcycles: [],\n\t\t\tstartNodeIds: [],\n\t\t\tterminalNodeIds: [],\n\t\t\tnodeCount: 0,\n\t\t\tedgeCount: 0,\n\t\t\tisDag: true,\n\t\t}\n\t}\n\n\tconst cycles = checkForCycles(blueprint)\n\tconst nodeCount = blueprint.nodes.length\n\tconst edgeCount = blueprint.edges?.length || 0\n\n\tconst nodesWithIncoming = new Set<string>()\n\tfor (const edge of blueprint.edges || []) {\n\t\tnodesWithIncoming.add(edge.target)\n\t}\n\n\tconst startNodeIds = blueprint.nodes.map((node) => node.id).filter((nodeId) => !nodesWithIncoming.has(nodeId))\n\n\tconst nodesWithOutgoing = new Set<string>()\n\tfor (const edge of blueprint.edges || []) {\n\t\tnodesWithOutgoing.add(edge.source)\n\t}\n\n\tconst terminalNodeIds = blueprint.nodes.map((node) => node.id).filter((nodeId) => !nodesWithOutgoing.has(nodeId))\n\n\treturn {\n\t\tcycles,\n\t\tstartNodeIds,\n\t\tterminalNodeIds,\n\t\tnodeCount,\n\t\tedgeCount,\n\t\tisDag: cycles.length === 0,\n\t}\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/context.ts"],"names":[],"mappings":";AAKO,IAAM,UAAN,MAAsF;AAAA,EAC5E,IAAA,GAAO,MAAA;AAAA,EACf,IAAA;AAAA,EAER,WAAA,CAAY,WAAA,GAAiC,EAAC,EAAG;AAChD,IAAA,IAAA,CAAK,OAAO,IAAI,GAAA,CAAI,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAC,CAAA;AAAA,EAChD;AAAA,EAEA,IAA8B,GAAA,EAAiC;AAC9D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,EACjC;AAAA,EAEA,GAAA,CAA8B,KAAQ,KAAA,EAA0B;AAC/D,IAAA,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,GAAG,GAAG,KAAK,CAAA;AAAA,EACjC;AAAA,EAEA,IAA8B,GAAA,EAAiB;AAC9C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,EACjC;AAAA,EAEA,OAAiC,GAAA,EAAiB;AACjD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,EACpC;AAAA,EAEA,MAAA,GAA8B;AAC7B,IAAA,OAAO,MAAA,CAAO,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AAAA,EACpC;AACD;AAMO,IAAM,mBAAN,MAAgG;AAAA,EAGtG,YAAoB,WAAA,EAAqC;AAArC,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA,EAAsC;AAAA,EAF1C,IAAA,GAAO,OAAA;AAAA,EAIvB,IAA8B,GAAA,EAA0C;AACvE,IAAA,OAAO,QAAQ,OAAA,CAAQ,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,EACjD;AAAA,EAEA,GAAA,CAA8B,KAAQ,KAAA,EAAmC;AACxE,IAAA,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAC/B,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACxB;AAAA,EAEA,IAA8B,GAAA,EAA0B;AACvD,IAAA,OAAO,QAAQ,OAAA,CAAQ,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,EACjD;AAAA,EAEA,OAAiC,GAAA,EAA0B;AAC1D,IAAA,OAAO,QAAQ,OAAA,CAAQ,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,EACpD;AAAA,EAEA,MAAA,GAAuC;AACtC,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,WAAA,CAAY,QAAQ,CAAA;AAAA,EACjD;AACD","file":"chunk-KWQHFT7E.js","sourcesContent":["import type { IAsyncContext, ISyncContext } 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\t\treturn this.data.get(String(key))\n\t}\n\n\tset<K extends keyof TContext>(key: K, value: TContext[K]): void {\n\t\tthis.data.set(String(key), value)\n\t}\n\n\thas<K extends keyof TContext>(key: K): boolean {\n\t\treturn this.data.has(String(key))\n\t}\n\n\tdelete<K extends keyof TContext>(key: K): boolean {\n\t\treturn this.data.delete(String(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\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\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\t\treturn Promise.resolve(this.syncContext.has(key))\n\t}\n\n\tdelete<K extends keyof TContext>(key: K): 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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/traverser.ts"],"names":["nodeId"],"mappings":"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","file":"chunk-NBIRTKZ7.js","sourcesContent":["import { analyzeBlueprint } from '../analysis'\nimport { CancelledWorkflowError, NodeExecutionError } 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\tprivate getEffectiveJoinStrategy(nodeId: string): 'any' | 'all' {\n\t\tconst node = this.dynamicBlueprint.nodes.find((n) => n.id === nodeId)\n\t\tconst baseJoinStrategy = node?.config?.joinStrategy || 'all'\n\n\t\tif (node?.uses === 'loop-controller') {\n\t\t\treturn 'any'\n\t\t}\n\n\t\tconst predecessors = this.allPredecessors.get(nodeId)\n\t\tif (predecessors) {\n\t\t\tfor (const predecessorId of predecessors) {\n\t\t\t\tconst predecessorNode = this.dynamicBlueprint.nodes.find((n) => n.id === predecessorId)\n\t\t\t\tif (predecessorNode?.uses === 'loop-controller') {\n\t\t\t\t\treturn 'any'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn baseJoinStrategy\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 = this.getEffectiveJoinStrategy(node.id)\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 = this.getEffectiveJoinStrategy(potentialNextId)\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\tconst implementation = this.functionRegistry?.get(dynamicNode.uses) || this.runtime.registry[dynamicNode.uses]\n\t\t\t\tif (!implementation) {\n\t\t\t\t\tthrow new NodeExecutionError(\n\t\t\t\t\t\t`Implementation for '${dynamicNode.uses}' not found for dynamic node '${dynamicNode.id}' generated by node '${nodeId}'.`,\n\t\t\t\t\t\tdynamicNode.id,\n\t\t\t\t\t\tthis.dynamicBlueprint.id,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tthis.executionId,\n\t\t\t\t\t)\n\t\t\t\t}\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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/adapter.ts"],"names":["nodeId"],"mappings":"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","file":"chunk-O3XD45IL.js","sourcesContent":["import { analyzeBlueprint } from '../analysis'\nimport { JsonSerializer } from '../serializer'\nimport type {\n\tIAsyncContext,\n\tISerializer,\n\tNodeResult,\n\tRuntimeOptions,\n\tWorkflowBlueprint,\n\tWorkflowResult,\n} from '../types'\nimport { FlowRuntime } from './runtime'\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/** Deletes a key. Used for cleanup. */\n\tdelete: (key: string) => Promise<void>\n}\n\n/** Configuration options for constructing a BaseDistributedAdapter. */\nexport interface AdapterOptions {\n\truntimeOptions: RuntimeOptions<any>\n\tcoordinationStore: ICoordinationStore\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\n\tconstructor(options: AdapterOptions) {\n\t\tthis.runtime = new FlowRuntime(options.runtimeOptions)\n\t\tthis.store = options.coordinationStore\n\t\tthis.serializer = options.runtimeOptions.serializer || new JsonSerializer()\n\t\tconsole.log('[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\tconsole.log('[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 * 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\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\tconsole.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\t// persist the blueprintId 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}\n\t\tconst workerState = {\n\t\t\tgetContext: () => context,\n\t\t\tmarkFallbackExecuted: () => {},\n\t\t\taddError: (nodeId: string, error: Error) => {\n\t\t\t\tconsole.error(`[Adapter] Error in node ${nodeId}:`, error)\n\t\t\t},\n\t\t} as any\n\n\t\ttry {\n\t\t\tconst result: NodeResult<any, any> = await this.runtime.executeNode(blueprint, nodeId, workerState)\n\t\t\tawait context.set(nodeId as any, result.output)\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 completedNodes = new Set(\n\t\t\t\t\tObject.keys(await context.toJSON()).filter((k) => blueprint.nodes.some((n) => n.id === k)),\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\tconsole.log(`[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\treturn\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\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)\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\tconsole.log(\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\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)\n\t\t\t\tconst isReady = await this.isReadyForFanIn(runId, blueprint, nextNodeDef.id)\n\t\t\t\tif (isReady) {\n\t\t\t\t\tconsole.log(`[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} else {\n\t\t\t\t\tconsole.log(`[Adapter] Node '${nextNodeDef.id}' is waiting for other predecessors to complete.`)\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\tconsole.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\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.setIfNotExist(poisonKey, 'poisoned', 3600))\n\t\tif (isPoisoned) {\n\t\t\tconsole.log(`[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\treturn await this.store.setIfNotExist(lockKey, 'locked', 3600)\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\tconst blueprintId = (await context.get('blueprintId' as any)) as string | undefined\n\n\t\tif (!blueprintId) {\n\t\t\tthrow new Error(`Cannot reconcile runId '${runId}': blueprintId not found in context.`)\n\t\t}\n\t\tconst blueprint = this.runtime.options.blueprints?.[blueprintId]\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\t// filter out internal keys\n\t\tconst completedNodes = new Set(Object.keys(state).filter((k) => blueprint.nodes.some((n) => n.id === k)))\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\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\tconsole.log(`[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\tconsole.log(`[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\tconsole.log(`[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 of a failed node to prevent stalling.\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 && (node.config?.joinStrategy || 'all') === 'all')\n\n\t\tfor (const successor of successors) {\n\t\t\tif (successor) {\n\t\t\t\tconst poisonKey = `flowcraft:fanin:poison:${runId}:${successor.id}`\n\t\t\t\tawait this.store.setIfNotExist(poisonKey, 'poisoned', 3600)\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[Adapter] Wrote poison pill for join node '${successor.id}' due to failed predecessor '${failedNodeId}'`,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/linter.ts"],"names":["e"],"mappings":";;;AA6BO,SAAS,aAAA,CACf,WACA,QAAA,EACe;AACf,EAAA,MAAM,SAAwB,EAAC;AAC/B,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,SAAA,CAAU,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AACxD,EAAA,MAAM,YAAA,GAAe,QAAA,YAAoB,GAAA,GAAM,IAAI,IAAI,QAAA,CAAS,IAAA,EAAM,CAAA,GAAI,IAAI,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAC,CAAA;AAGvG,EAAA,KAAA,MAAW,IAAA,IAAQ,UAAU,KAAA,EAAO;AACnC,IAAA,IAAI,CAAC,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,QAAQ,KAAK,CAAC,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA,IAAK,CAAC,aAAa,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAG;AACtG,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACX,IAAA,EAAM,6BAAA;AAAA,QACN,OAAA,EAAS,CAAA,yBAAA,EAA4B,IAAA,CAAK,IAAI,CAAA,wCAAA,CAAA;AAAA,QAC9C,QAAQ,IAAA,CAAK;AAAA,OACb,CAAA;AAAA,IACF;AAAA,EACD;AAGA,EAAA,KAAA,MAAW,IAAA,IAAQ,SAAA,CAAU,KAAA,IAAS,EAAC,EAAG;AACzC,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,EAAG;AAC9B,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACX,IAAA,EAAM,qBAAA;AAAA,QACN,OAAA,EAAS,CAAA,aAAA,EAAgB,IAAA,CAAK,MAAM,CAAA,yCAAA,CAAA;AAAA,QACpC,WAAW,IAAA,CAAK;AAAA,OAChB,CAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,EAAG;AAC9B,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACX,IAAA,EAAM,qBAAA;AAAA,QACN,OAAA,EAAS,CAAA,aAAA,EAAgB,IAAA,CAAK,MAAM,CAAA,yCAAA,CAAA;AAAA,QACpC,WAAW,IAAA,CAAK;AAAA,OAChB,CAAA;AAAA,IACF;AAAA,EACD;AAGA,EAAA,IAAI,SAAA,CAAU,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AAC/B,IAAA,MAAM,QAAA,GAAW,iBAAiB,SAAS,CAAA;AAC3C,IAAA,MAAM,cAAA,uBAAqB,GAAA,EAAY;AACvC,IAAA,MAAM,YAAA,GAAe,CAAC,GAAG,QAAA,CAAS,YAAY,CAAA;AAC9C,IAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEhC,IAAA,OAAO,YAAA,CAAa,SAAS,CAAA,EAAG;AAC/B,MAAA,MAAM,SAAA,GAAY,aAAa,GAAA,EAAI;AACnC,MAAA,IAAI,CAAC,SAAA,IAAa,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA,EAAG;AAE1C,MAAA,OAAA,CAAQ,IAAI,SAAS,CAAA;AACrB,MAAA,cAAA,CAAe,IAAI,SAAS,CAAA;AAE5B,MAAA,KAAA,MAAW,CAAA,IAAK,UAAU,KAAA,CAAM,MAAA,CAAO,CAACA,EAAAA,KAAMA,EAAAA,CAAE,MAAA,KAAW,SAAS,CAAA,EAAG;AACtE,QAAA,YAAA,CAAa,IAAA,CAAK,EAAE,MAAM,CAAA;AAAA,MAC3B;AAAA,IACD;AAEA,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC7B,MAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,MAAM,CAAA,EAAG;AAChC,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACX,IAAA,EAAM,aAAA;AAAA,UACN,OAAA,EAAS,SAAS,MAAM,CAAA,uCAAA,CAAA;AAAA,UACxB;AAAA,SACA,CAAA;AAAA,MACF;AAAA,IACD;AAAA,EACD;AAEA,EAAA,OAAO;AAAA,IACN,OAAA,EAAS,OAAO,MAAA,KAAW,CAAA;AAAA,IAC3B;AAAA,GACD;AACD","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"]}