@magic-marker/nurt 0.1.0 → 0.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.
- package/README.md +66 -0
- package/dist/{flow-DqIejS_0.d.ts → flow-dRTAsU3_.d.ts} +2 -1
- package/dist/index.d.ts +31 -3
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/package.json +13 -14
package/README.md
CHANGED
|
@@ -103,6 +103,36 @@ Chainable builder. Each `.step()` call returns a new builder with an expanded ty
|
|
|
103
103
|
})
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
#### `.step(name, parents, inputMapper, handler | options)` - Step with typed input mapping
|
|
107
|
+
|
|
108
|
+
Cherry-pick or restructure parent outputs with full type inference before passing to the handler.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
.step("summarize", ["userStep", "configStep"],
|
|
112
|
+
(input) => ({
|
|
113
|
+
name: input.userStep.name,
|
|
114
|
+
maxRetries: input.configStep.maxRetries,
|
|
115
|
+
}),
|
|
116
|
+
async (mapped) => {
|
|
117
|
+
// mapped is typed as { name: string; maxRetries: number }
|
|
118
|
+
return `${mapped.name}: ${mapped.maxRetries} retries`;
|
|
119
|
+
},
|
|
120
|
+
)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The input mapper can also be paired with an options object instead of a plain handler:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
.step("save", ["process"],
|
|
127
|
+
(input) => input.process.data,
|
|
128
|
+
{
|
|
129
|
+
execute: async (data) => ({ saved: true }),
|
|
130
|
+
terminal: true,
|
|
131
|
+
allowFailures: true,
|
|
132
|
+
},
|
|
133
|
+
)
|
|
134
|
+
```
|
|
135
|
+
|
|
106
136
|
#### `.group<T>(name, options)` - Declare a group
|
|
107
137
|
|
|
108
138
|
```typescript
|
|
@@ -275,6 +305,42 @@ const result = await flow("parallel")
|
|
|
275
305
|
// branch-a and branch-b execute concurrently
|
|
276
306
|
```
|
|
277
307
|
|
|
308
|
+
### Input Mapping
|
|
309
|
+
|
|
310
|
+
Use the 4-argument form of `.step()` to cherry-pick values and restructure parent outputs before they reach the handler. The input mapper receives fully-typed parent outputs and returns a custom shape that becomes the handler's input.
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
const result = await flow("mapped")
|
|
314
|
+
.step("user", async () => ({
|
|
315
|
+
name: "Alice",
|
|
316
|
+
age: 30,
|
|
317
|
+
preferences: { theme: "dark" },
|
|
318
|
+
}))
|
|
319
|
+
.step("config", async () => ({
|
|
320
|
+
maxRetries: 3,
|
|
321
|
+
timeout: 5000,
|
|
322
|
+
debug: false,
|
|
323
|
+
}))
|
|
324
|
+
// Cherry-pick only what's needed from multiple parents
|
|
325
|
+
.step(
|
|
326
|
+
"greeting",
|
|
327
|
+
["user", "config"],
|
|
328
|
+
(input) => ({
|
|
329
|
+
name: input.user.name,
|
|
330
|
+
theme: input.user.preferences.theme,
|
|
331
|
+
timeout: input.config.timeout,
|
|
332
|
+
}),
|
|
333
|
+
async (mapped) => {
|
|
334
|
+
// mapped is { name: string; theme: string; timeout: number }
|
|
335
|
+
return `Hello ${mapped.name} (${mapped.theme} theme, ${mapped.timeout}ms timeout)`;
|
|
336
|
+
},
|
|
337
|
+
)
|
|
338
|
+
.build()
|
|
339
|
+
.run().result;
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
This is especially useful when parent outputs are large or deeply nested and your step only needs a few values. Unlike the `transform` field in the options object (which is untyped), the positional input mapper provides full type inference on both sides.
|
|
343
|
+
|
|
278
344
|
### Dynamic Group Spawning (Arbiter Pattern)
|
|
279
345
|
|
|
280
346
|
An arbiter step decides at runtime which members to add to a group.
|
|
@@ -34,6 +34,7 @@ interface Executable<TInput, TOutput> {
|
|
|
34
34
|
execute(input: TInput, ctx: StepContext): Promise<TOutput>;
|
|
35
35
|
}
|
|
36
36
|
type StepHandler<TInput, TOutput> = ((input: TInput, ctx: StepContext) => Promise<TOutput>) | Executable<TInput, TOutput>;
|
|
37
|
+
type InputMapper<TParentOutputs, TMapped> = (parentOutputs: TParentOutputs) => TMapped;
|
|
37
38
|
interface StepOptions<TInput, TOutput> {
|
|
38
39
|
allowFailures?: boolean;
|
|
39
40
|
execute: StepHandler<TInput, TOutput>;
|
|
@@ -303,4 +304,4 @@ declare class Flow<TRegistry extends Record<string, unknown> = Record<string, un
|
|
|
303
304
|
run(options?: RunOptions): FlowRun<TRegistry>;
|
|
304
305
|
}
|
|
305
306
|
|
|
306
|
-
export { isGroupRef as A, isSubgraphMember as B, type Executable as E, Flow as F, type GroupDefinition as G, History as H, type ParentOutputs as P, type ResolveInput as R, type StepDefinition as S, type StepHandler as a, type StepOptions as b, type GroupRef as c, type SubgraphMember as d, type StepStatus as e, type FlowHooks as f, FlowRun as g, type FlowRunResult as h, type FlowSnapshot as i, type FlowSnapshotGroup as j, type FlowSnapshotGroupMember as k, type FlowSnapshotStep as l, type GroupMember as m, type GroupMemberRuntime as n, type GroupRuntime as o, type RunHandle as p, type RunOptions as q, type RunStatus as r, type SingleMember as s, type StepContext as t, type StepRecord as u, type StepResult as v, createSnapshot as w, group as x, invokeHandler as y, isExecutable as z };
|
|
307
|
+
export { isGroupRef as A, isSubgraphMember as B, type Executable as E, Flow as F, type GroupDefinition as G, History as H, type InputMapper as I, type ParentOutputs as P, type ResolveInput as R, type StepDefinition as S, type StepHandler as a, type StepOptions as b, type GroupRef as c, type SubgraphMember as d, type StepStatus as e, type FlowHooks as f, FlowRun as g, type FlowRunResult as h, type FlowSnapshot as i, type FlowSnapshotGroup as j, type FlowSnapshotGroupMember as k, type FlowSnapshotStep as l, type GroupMember as m, type GroupMemberRuntime as n, type GroupRuntime as o, type RunHandle as p, type RunOptions as q, type RunStatus as r, type SingleMember as s, type StepContext as t, type StepRecord as u, type StepResult as v, createSnapshot as w, group as x, invokeHandler as y, isExecutable as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as StepDefinition, G as GroupDefinition, a as StepHandler, b as StepOptions, c as GroupRef, F as Flow, d as SubgraphMember, e as StepStatus } from './flow-
|
|
2
|
-
export { E as Executable, f as FlowHooks, g as FlowRun, h as FlowRunResult, i as FlowSnapshot, j as FlowSnapshotGroup, k as FlowSnapshotGroupMember, l as FlowSnapshotStep, m as GroupMember, n as GroupMemberRuntime, o as GroupRuntime, H as History, P as ParentOutputs, R as ResolveInput, p as RunHandle, q as RunOptions, r as RunStatus, s as SingleMember, t as StepContext, u as StepRecord, v as StepResult, w as createSnapshot, x as group, y as invokeHandler, z as isExecutable, A as isGroupRef, B as isSubgraphMember } from './flow-
|
|
1
|
+
import { S as StepDefinition, G as GroupDefinition, a as StepHandler, b as StepOptions, c as GroupRef, I as InputMapper, F as Flow, d as SubgraphMember, e as StepStatus } from './flow-dRTAsU3_.js';
|
|
2
|
+
export { E as Executable, f as FlowHooks, g as FlowRun, h as FlowRunResult, i as FlowSnapshot, j as FlowSnapshotGroup, k as FlowSnapshotGroupMember, l as FlowSnapshotStep, m as GroupMember, n as GroupMemberRuntime, o as GroupRuntime, H as History, P as ParentOutputs, R as ResolveInput, p as RunHandle, q as RunOptions, r as RunStatus, s as SingleMember, t as StepContext, u as StepRecord, v as StepResult, w as createSnapshot, x as group, y as invokeHandler, z as isExecutable, A as isGroupRef, B as isSubgraphMember } from './flow-dRTAsU3_.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Chainable builder for constructing type-safe flow graphs.
|
|
@@ -43,6 +43,34 @@ declare class FlowBuilder<TRegistry extends Record<string, unknown> = {}> {
|
|
|
43
43
|
}, TOutput> | StepOptions<{
|
|
44
44
|
[K in TDeps[number] as K extends string ? K : K extends GroupRef<infer G> ? G : never]: K extends string ? TRegistry[K & keyof TRegistry] : K extends GroupRef<infer G> ? TRegistry[G & keyof TRegistry] : never;
|
|
45
45
|
}, TOutput>): FlowBuilder<TRegistry & Record<TName, TOutput>>;
|
|
46
|
+
/**
|
|
47
|
+
* Step with parents + typed input mapper + handler.
|
|
48
|
+
* .step("name", ["parent1"], mapper, executeFn)
|
|
49
|
+
*/
|
|
50
|
+
step<TName extends string, TParents extends readonly (keyof TRegistry & string)[], TMapped, TOutput>(name: TName, parents: [...TParents], inputMapper: InputMapper<{
|
|
51
|
+
[K in TParents[number]]: TRegistry[K];
|
|
52
|
+
}, TMapped>, handler: StepHandler<TMapped, TOutput>): FlowBuilder<TRegistry & Record<TName, TOutput>>;
|
|
53
|
+
/**
|
|
54
|
+
* Step with parents + typed input mapper + options.
|
|
55
|
+
* .step("name", ["parent1"], mapper, { execute, terminal?, allowFailures? })
|
|
56
|
+
*/
|
|
57
|
+
step<TName extends string, TParents extends readonly (keyof TRegistry & string)[], TMapped, TOutput>(name: TName, parents: [...TParents], inputMapper: InputMapper<{
|
|
58
|
+
[K in TParents[number]]: TRegistry[K];
|
|
59
|
+
}, TMapped>, options: Omit<StepOptions<TMapped, TOutput>, "transform">): FlowBuilder<TRegistry & Record<TName, TOutput>>;
|
|
60
|
+
/**
|
|
61
|
+
* Step with group ref dependencies + typed input mapper + handler.
|
|
62
|
+
* .step("name", [group("reviews")], mapper, executeFn)
|
|
63
|
+
*/
|
|
64
|
+
step<TName extends string, TDeps extends readonly unknown[], TMapped, TOutput>(name: TName, deps: [...TDeps], inputMapper: InputMapper<{
|
|
65
|
+
[K in TDeps[number] as K extends string ? K : K extends GroupRef<infer G> ? G : never]: K extends string ? TRegistry[K & keyof TRegistry] : K extends GroupRef<infer G> ? TRegistry[G & keyof TRegistry] : never;
|
|
66
|
+
}, TMapped>, handler: StepHandler<TMapped, TOutput>): FlowBuilder<TRegistry & Record<TName, TOutput>>;
|
|
67
|
+
/**
|
|
68
|
+
* Step with group ref dependencies + typed input mapper + options.
|
|
69
|
+
* .step("name", [group("reviews")], mapper, { execute, terminal?, allowFailures? })
|
|
70
|
+
*/
|
|
71
|
+
step<TName extends string, TDeps extends readonly unknown[], TMapped, TOutput>(name: TName, deps: [...TDeps], inputMapper: InputMapper<{
|
|
72
|
+
[K in TDeps[number] as K extends string ? K : K extends GroupRef<infer G> ? G : never]: K extends string ? TRegistry[K & keyof TRegistry] : K extends GroupRef<infer G> ? TRegistry[G & keyof TRegistry] : never;
|
|
73
|
+
}, TMapped>, options: Omit<StepOptions<TMapped, TOutput>, "transform">): FlowBuilder<TRegistry & Record<TName, TOutput>>;
|
|
46
74
|
/**
|
|
47
75
|
* Declare a typed group for dynamic fan-in.
|
|
48
76
|
* .group<TOut>("reviews", { dependsOn: ["arbiter"] })
|
|
@@ -133,4 +161,4 @@ declare function getSkippableSteps(steps: readonly StepDefinition[], statuses: R
|
|
|
133
161
|
*/
|
|
134
162
|
declare function getReadyWithFailures(steps: readonly StepDefinition[], statuses: ReadonlyMap<string, StepStatus>): string[];
|
|
135
163
|
|
|
136
|
-
export { CycleDetectedError, DuplicateStepError, Flow, FlowBuilder, GroupRef, type PipelineStepDef, StepDefinition, StepExecutionError, StepHandler, StepOptions, StepStatus, SubgraphMember, UnfilledSlotError, UnknownParentError, UnsealedGroupError, flow, getReadySteps, getReadyWithFailures, getSkippableSteps, pipeline, topologicalSort, validateAcyclic };
|
|
164
|
+
export { CycleDetectedError, DuplicateStepError, Flow, FlowBuilder, GroupRef, InputMapper, type PipelineStepDef, StepDefinition, StepExecutionError, StepHandler, StepOptions, StepStatus, SubgraphMember, UnfilledSlotError, UnknownParentError, UnsealedGroupError, flow, getReadySteps, getReadyWithFailures, getSkippableSteps, pipeline, topologicalSort, validateAcyclic };
|
package/dist/index.js
CHANGED
|
@@ -862,7 +862,7 @@ var FlowBuilder = class _FlowBuilder {
|
|
|
862
862
|
}
|
|
863
863
|
// Implementation
|
|
864
864
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
865
|
-
step(name, parentsOrHandler, handlerOrOptions) {
|
|
865
|
+
step(name, parentsOrHandler, handlerOrOptions, stepDef) {
|
|
866
866
|
if (this.knownNames.has(name)) {
|
|
867
867
|
throw new DuplicateStepError(name);
|
|
868
868
|
}
|
|
@@ -876,7 +876,17 @@ var FlowBuilder = class _FlowBuilder {
|
|
|
876
876
|
if (isGroupRef(p)) return p.groupName;
|
|
877
877
|
return p;
|
|
878
878
|
});
|
|
879
|
-
if (
|
|
879
|
+
if (stepDef !== void 0) {
|
|
880
|
+
transform = handlerOrOptions;
|
|
881
|
+
if (typeof stepDef === "object" && stepDef !== null && "execute" in stepDef) {
|
|
882
|
+
const opts = stepDef;
|
|
883
|
+
handler = opts.execute;
|
|
884
|
+
allowFailures = opts.allowFailures ?? false;
|
|
885
|
+
terminal = opts.terminal ?? false;
|
|
886
|
+
} else {
|
|
887
|
+
handler = stepDef;
|
|
888
|
+
}
|
|
889
|
+
} else if (typeof handlerOrOptions === "object" && handlerOrOptions !== null && "execute" in handlerOrOptions) {
|
|
880
890
|
const opts = handlerOrOptions;
|
|
881
891
|
handler = opts.execute;
|
|
882
892
|
allowFailures = opts.allowFailures ?? false;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/graph.ts","../src/types.ts","../src/snapshot.ts","../src/group.ts","../src/history.ts","../src/flow-run.ts","../src/flow.ts","../src/flow-builder.ts","../src/pipeline.ts"],"sourcesContent":["export class CycleDetectedError extends Error {\n constructor(cycle: string[]) {\n super(`Cycle detected in flow graph: ${cycle.join(\" → \")}`);\n this.name = \"CycleDetectedError\";\n }\n}\n\nexport class DuplicateStepError extends Error {\n constructor(name: string) {\n super(`Step \"${name}\" is already registered`);\n this.name = \"DuplicateStepError\";\n }\n}\n\nexport class UnknownParentError extends Error {\n constructor(stepName: string, parentName: string) {\n super(`Step \"${stepName}\" depends on unknown parent \"${parentName}\"`);\n this.name = \"UnknownParentError\";\n }\n}\n\nexport class UnsealedGroupError extends Error {\n constructor(groupName: string) {\n super(`Group \"${groupName}\" was never sealed`);\n this.name = \"UnsealedGroupError\";\n }\n}\n\nexport class UnfilledSlotError extends Error {\n constructor(slotPath: string) {\n super(`Slot \"${slotPath}\" was not provided an implementation`);\n this.name = \"UnfilledSlotError\";\n }\n}\n\nexport class StepExecutionError extends Error {\n readonly stepName: string;\n readonly cause: unknown;\n\n constructor(stepName: string, cause: unknown) {\n const message = cause instanceof Error ? cause.message : String(cause);\n super(`Step \"${stepName}\" failed: ${message}`);\n this.name = \"StepExecutionError\";\n this.stepName = stepName;\n this.cause = cause;\n }\n}\n","import { CycleDetectedError } from \"./errors.js\";\nimport type { StepDefinition, StepStatus } from \"./types.js\";\n\nexport interface GraphNode {\n readonly name: string;\n readonly parentNames: readonly string[];\n}\n\n/**\n * Validates that the graph has no cycles using Kahn's algorithm.\n * Throws CycleDetectedError if a cycle is found.\n */\nexport function validateAcyclic(nodes: readonly GraphNode[]): void {\n const inDegree = new Map<string, number>();\n const children = new Map<string, string[]>();\n\n for (const node of nodes) {\n if (!inDegree.has(node.name)) {\n inDegree.set(node.name, 0);\n }\n if (!children.has(node.name)) {\n children.set(node.name, []);\n }\n for (const parent of node.parentNames) {\n if (!children.has(parent)) {\n children.set(parent, []);\n }\n children.get(parent)!.push(node.name);\n inDegree.set(node.name, (inDegree.get(node.name) ?? 0) + 1);\n }\n }\n\n const queue: string[] = [];\n for (const [name, degree] of inDegree) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n let visited = 0;\n while (queue.length > 0) {\n const current = queue.shift()!;\n visited++;\n for (const child of children.get(current) ?? []) {\n const newDegree = inDegree.get(child)! - 1;\n inDegree.set(child, newDegree);\n if (newDegree === 0) {\n queue.push(child);\n }\n }\n }\n\n if (visited < nodes.length) {\n const remaining = nodes\n .filter((n) => (inDegree.get(n.name) ?? 0) > 0)\n .map((n) => n.name);\n throw new CycleDetectedError(remaining);\n }\n}\n\n/**\n * Returns a valid topological ordering of the nodes.\n * Assumes the graph is acyclic (call validateAcyclic first).\n */\nexport function topologicalSort(nodes: readonly GraphNode[]): string[] {\n const inDegree = new Map<string, number>();\n const children = new Map<string, string[]>();\n\n for (const node of nodes) {\n if (!inDegree.has(node.name)) {\n inDegree.set(node.name, 0);\n }\n if (!children.has(node.name)) {\n children.set(node.name, []);\n }\n for (const parent of node.parentNames) {\n if (!children.has(parent)) {\n children.set(parent, []);\n }\n children.get(parent)!.push(node.name);\n inDegree.set(node.name, (inDegree.get(node.name) ?? 0) + 1);\n }\n }\n\n const queue: string[] = [];\n for (const [name, degree] of inDegree) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n const sorted: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift()!;\n sorted.push(current);\n for (const child of children.get(current) ?? []) {\n const newDegree = inDegree.get(child)! - 1;\n inDegree.set(child, newDegree);\n if (newDegree === 0) {\n queue.push(child);\n }\n }\n }\n\n return sorted;\n}\n\n/**\n * Returns names of steps that are ready to execute:\n * all parents have completed with \"success\" status.\n */\nexport function getReadySteps(\n steps: readonly GraphNode[],\n statuses: ReadonlyMap<string, StepStatus>,\n): string[] {\n const ready: string[] = [];\n\n for (const step of steps) {\n const status = statuses.get(step.name);\n if (status !== \"pending\") continue;\n\n const allParentsDone = step.parentNames.every((parent) => {\n const parentStatus = statuses.get(parent);\n return parentStatus === \"success\";\n });\n\n if (allParentsDone) {\n ready.push(step.name);\n }\n }\n\n return ready;\n}\n\n/**\n * Returns names of steps that should be skipped because\n * at least one parent has \"error\" or \"skipped\" status\n * and the step does NOT have allowFailures set.\n */\nexport function getSkippableSteps(\n steps: readonly StepDefinition[],\n statuses: ReadonlyMap<string, StepStatus>,\n): string[] {\n const skippable: string[] = [];\n\n for (const step of steps) {\n const status = statuses.get(step.name);\n if (status !== \"pending\") continue;\n if (step.allowFailures) continue;\n\n const hasFailedParent = step.parentNames.some((parent) => {\n const parentStatus = statuses.get(parent);\n return parentStatus === \"error\" || parentStatus === \"skipped\";\n });\n\n if (hasFailedParent) {\n skippable.push(step.name);\n }\n }\n\n return skippable;\n}\n\n/**\n * Returns names of steps with allowFailures that are ready to execute:\n * all parents have completed (success, error, or skipped).\n */\nexport function getReadyWithFailures(\n steps: readonly StepDefinition[],\n statuses: ReadonlyMap<string, StepStatus>,\n): string[] {\n const ready: string[] = [];\n\n for (const step of steps) {\n const status = statuses.get(step.name);\n if (status !== \"pending\") continue;\n if (!step.allowFailures) continue;\n\n const allParentsSettled = step.parentNames.every((parent) => {\n const parentStatus = statuses.get(parent);\n return (\n parentStatus === \"success\" ||\n parentStatus === \"error\" ||\n parentStatus === \"skipped\"\n );\n });\n\n if (allParentsSettled) {\n ready.push(step.name);\n }\n }\n\n return ready;\n}\n","import type { History } from \"./history.js\";\n\n// --- Status types ---\n\nexport type StepStatus =\n | \"pending\"\n | \"running\"\n | \"success\"\n | \"error\"\n | \"skipped\";\n\nexport type RunStatus = \"idle\" | \"running\" | \"success\" | \"error\";\n\n// --- Step result (for allowFailures) ---\n\nexport type StepResult<T> =\n | { status: \"success\"; value: T }\n | { error: string; status: \"error\" }\n | { status: \"skipped\" };\n\n// --- Run handle (exposed to steps via context) ---\n\nexport interface RunHandle {\n addGroupMember(groupName: string, member: GroupMember): void;\n provide(path: string, value: unknown): void;\n sealGroup(groupName: string): void;\n spawnGroup(groupName: string, members: readonly GroupMember[]): void;\n}\n\n// --- Context ---\n\nexport interface StepContext {\n readonly history: History;\n provided<T>(): T;\n readonly run: RunHandle;\n readonly runId: string;\n readonly signal: AbortSignal;\n}\n\n// --- Executable interface ---\n\nexport interface Executable<TInput, TOutput> {\n execute(input: TInput, ctx: StepContext): Promise<TOutput>;\n}\n\n// --- Step handler union ---\n\nexport type StepHandler<TInput, TOutput> =\n | ((input: TInput, ctx: StepContext) => Promise<TOutput>)\n | Executable<TInput, TOutput>;\n\n// --- Step options ---\n\nexport interface StepOptions<TInput, TOutput> {\n allowFailures?: boolean;\n execute: StepHandler<TInput, TOutput>;\n terminal?: boolean;\n transform?: (parentOutputs: unknown) => TInput;\n}\n\n// --- Step definition (internal) ---\n\nexport interface StepDefinition {\n readonly allowFailures: boolean;\n readonly handler: StepHandler<unknown, unknown>;\n readonly name: string;\n readonly parentNames: readonly string[];\n readonly terminal: boolean;\n readonly transform?: (parentOutputs: unknown) => unknown;\n}\n\n// --- Group definition (internal) ---\n\nexport interface GroupDefinition {\n readonly dependsOn: readonly string[];\n readonly name: string;\n}\n\n// --- Step record (runtime) ---\n\nexport interface StepRecord {\n completedAt?: number;\n durationMs?: number;\n error?: string;\n readonly name: string;\n output?: unknown;\n readonly parentNames: readonly string[];\n startedAt?: number;\n status: StepStatus;\n}\n\n// --- Run result ---\n\nexport interface FlowRunResult {\n readonly completedAt: number;\n readonly history: ReadonlyMap<string, unknown>;\n readonly runId: string;\n readonly startedAt: number;\n readonly status: RunStatus;\n readonly steps: readonly StepRecord[];\n}\n\n// --- Hooks ---\n\nexport interface FlowHooks {\n onChange?: () => void;\n onRunComplete?: (result: FlowRunResult) => void;\n onStepAdded?: (step: StepRecord) => void;\n onStepComplete?: (step: StepRecord) => void;\n onStepError?: (step: StepRecord) => void;\n onStepStart?: (step: StepRecord) => void;\n}\n\n// --- Run options ---\n\nexport interface RunOptions {\n failFast?: boolean;\n hooks?: FlowHooks;\n injectedSteps?: Map<string, unknown>;\n}\n\n// --- Group ref marker ---\n\nconst GROUP_REF_BRAND = Symbol(\"GroupRef\");\n\nexport interface GroupRef<K extends string> {\n readonly [GROUP_REF_BRAND]: true;\n readonly groupName: K;\n}\n\nexport function group<K extends string>(name: K): GroupRef<K> {\n return { [GROUP_REF_BRAND]: true, groupName: name } as GroupRef<K>;\n}\n\nexport function isGroupRef(value: unknown): value is GroupRef<string> {\n return (\n typeof value === \"object\" && value !== null && GROUP_REF_BRAND in value\n );\n}\n\n// --- Type-level utilities ---\n\nexport type ParentOutputs<\n TRegistry extends Record<string, unknown>,\n TParents extends readonly (keyof TRegistry & string)[],\n> = { [K in TParents[number]]: TRegistry[K] };\n\n/**\n * Resolves a mixed dependency array (step names + group refs) to their types.\n */\nexport type ResolveInput<\n TRegistry extends Record<string, unknown>,\n TDeps extends readonly unknown[],\n> = {\n [K in TDeps[number] as K extends string\n ? K\n : K extends GroupRef<infer G>\n ? G\n : never]: K extends string\n ? TRegistry[K]\n : K extends GroupRef<infer G>\n ? TRegistry[G]\n : never;\n};\n\n// --- Group member types ---\n\nexport interface SingleMember<TInput, TOutput> {\n readonly execute: StepHandler<TInput, TOutput>;\n readonly name: string;\n}\n\nexport interface SubgraphMember {\n readonly externalDeps?: Record<string, string>;\n readonly flow: import(\"./flow.js\").Flow;\n readonly name: string;\n}\n\nexport type GroupMember = SingleMember<unknown, unknown> | SubgraphMember;\n\nexport function isSubgraphMember(\n member: GroupMember,\n): member is SubgraphMember {\n return \"flow\" in member;\n}\n\n// --- Handler detection ---\n\nexport function isExecutable(\n value: unknown,\n): value is Executable<unknown, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"execute\" in value &&\n typeof (value as Record<string, unknown>).execute === \"function\"\n );\n}\n\nexport function invokeHandler<TInput, TOutput>(\n handler: StepHandler<TInput, TOutput>,\n input: TInput,\n ctx: StepContext,\n): Promise<TOutput> {\n if (isExecutable(handler)) {\n return handler.execute(input, ctx);\n }\n return (handler as (input: TInput, ctx: StepContext) => Promise<TOutput>)(\n input,\n ctx,\n );\n}\n","import type { GroupMemberRuntime, GroupRuntime } from \"./group.js\";\nimport type { RunStatus, StepStatus } from \"./types.js\";\nimport { isSubgraphMember } from \"./types.js\";\n\n// --- Snapshot types (JSON-serializable) ---\n\nexport interface FlowSnapshot {\n flow: {\n groups: FlowSnapshotGroup[];\n name: string;\n steps: FlowSnapshotStep[];\n };\n run: {\n completedAt?: number;\n runId: string;\n startedAt: number;\n status: RunStatus;\n };\n}\n\nexport interface FlowSnapshotStep {\n allowFailures: boolean;\n completedAt?: number;\n durationMs?: number;\n error?: string;\n name: string;\n output?: unknown;\n parentNames: string[];\n startedAt?: number;\n status: StepStatus;\n terminal: boolean;\n}\n\nexport interface FlowSnapshotGroup {\n dependsOn: string[];\n members: FlowSnapshotGroupMember[];\n name: string;\n sealed: boolean;\n}\n\nexport interface FlowSnapshotGroupMember {\n completedAt?: number;\n durationMs?: number;\n error?: string;\n externalDeps?: Record<string, string>;\n name: string;\n output?: unknown;\n startedAt?: number;\n status: \"pending\" | \"running\" | \"success\" | \"error\";\n subgraph?: FlowSnapshot;\n type: \"single\" | \"subgraph\";\n}\n\n// --- Snapshot creation ---\n\nexport interface SnapshotInput {\n flow: {\n groups: ReadonlyArray<{ dependsOn: readonly string[]; name: string }>;\n name: string;\n steps: ReadonlyArray<{\n allowFailures: boolean;\n name: string;\n parentNames: readonly string[];\n terminal: boolean;\n }>;\n };\n groupRuntimes: ReadonlyMap<string, GroupRuntime>;\n run: {\n completedAt?: number;\n runId: string;\n startedAt: number;\n status: RunStatus;\n };\n stepRecords: ReadonlyMap<\n string,\n {\n completedAt?: number;\n durationMs?: number;\n error?: string;\n name: string;\n output?: unknown;\n parentNames: readonly string[];\n startedAt?: number;\n status: StepStatus;\n }\n >;\n}\n\nexport function createSnapshot(input: SnapshotInput): FlowSnapshot {\n const steps: FlowSnapshotStep[] = input.flow.steps.map((def) => {\n const record = input.stepRecords.get(def.name);\n return {\n allowFailures: def.allowFailures,\n completedAt: record?.completedAt,\n durationMs: record?.durationMs,\n error: record?.error,\n name: def.name,\n output: record?.output,\n parentNames: [...def.parentNames],\n startedAt: record?.startedAt,\n status: record?.status ?? \"pending\",\n terminal: def.terminal,\n };\n });\n\n const groups: FlowSnapshotGroup[] = input.flow.groups.map((groupDef) => {\n const runtime = input.groupRuntimes.get(groupDef.name);\n return {\n dependsOn: [...groupDef.dependsOn],\n members: runtime?.members.map(serializeGroupMember) ?? [],\n name: groupDef.name,\n sealed: runtime?.sealed ?? false,\n };\n });\n\n return {\n flow: {\n groups,\n name: input.flow.name,\n steps,\n },\n run: {\n completedAt: input.run.completedAt,\n runId: input.run.runId,\n startedAt: input.run.startedAt,\n status: input.run.status,\n },\n };\n}\n\nfunction serializeGroupMember(\n member: GroupMemberRuntime,\n): FlowSnapshotGroupMember {\n const isSubgraph = isSubgraphMember(member.member);\n const durationMs =\n member.startedAt && member.completedAt\n ? member.completedAt - member.startedAt\n : undefined;\n\n const result: FlowSnapshotGroupMember = {\n completedAt: member.completedAt,\n durationMs,\n error: member.error,\n name: member.name,\n output: member.output,\n startedAt: member.startedAt,\n status: member.status,\n type: isSubgraph ? \"subgraph\" : \"single\",\n };\n\n if (isSubgraph) {\n const sub = member.member as import(\"./types.js\").SubgraphMember;\n if (sub.externalDeps) {\n result.externalDeps = { ...sub.externalDeps };\n }\n if (member.childRun) {\n result.subgraph = member.childRun.snapshot();\n }\n }\n\n return result;\n}\n","import type { FlowRun } from \"./flow-run.js\";\nimport {\n type GroupMember,\n type SingleMember,\n type StepContext,\n type StepResult,\n invokeHandler,\n isSubgraphMember,\n} from \"./types.js\";\n\nexport interface GroupRuntime {\n readonly dependsOn: readonly string[];\n readonly members: GroupMemberRuntime[];\n readonly name: string;\n sealed: boolean;\n}\n\nexport interface GroupMemberRuntime {\n childRun?: FlowRun;\n completedAt?: number;\n error?: string;\n readonly member: GroupMember;\n readonly name: string;\n output?: unknown;\n startedAt?: number;\n status: \"pending\" | \"running\" | \"success\" | \"error\";\n}\n\n/**\n * Creates a new runtime group tracker.\n */\nexport function createGroupRuntime(\n name: string,\n dependsOn: readonly string[],\n): GroupRuntime {\n return {\n dependsOn,\n members: [],\n name,\n sealed: false,\n };\n}\n\n/**\n * Adds members to a group and optionally seals it.\n */\nexport function addGroupMembers(\n group: GroupRuntime,\n members: readonly GroupMember[],\n seal: boolean,\n): void {\n for (const member of members) {\n group.members.push({\n member,\n name: member.name,\n status: \"pending\",\n });\n }\n if (seal) {\n group.sealed = true;\n }\n}\n\n/**\n * Checks if a group is complete (sealed + all members done).\n */\nexport function isGroupComplete(group: GroupRuntime): boolean {\n if (!group.sealed) return false;\n return group.members.every(\n (m) => m.status === \"success\" || m.status === \"error\",\n );\n}\n\n/**\n * Collects outputs from all group members.\n * Returns StepResult[] for allowFailures consumers, or the raw values.\n */\nexport function collectGroupOutputs(\n group: GroupRuntime,\n): StepResult<unknown>[] {\n return group.members.map((m) => {\n if (m.status === \"success\") {\n return { status: \"success\" as const, value: m.output };\n }\n return {\n error: m.error ?? \"Unknown error\",\n status: \"error\" as const,\n };\n });\n}\n\n/**\n * Collects only successful outputs (for non-allowFailures consumers).\n */\nexport function collectSuccessOutputs(group: GroupRuntime): unknown[] {\n return group.members\n .filter((m) => m.status === \"success\")\n .map((m) => m.output);\n}\n\n/**\n * Executes a single group member (single-step or subgraph).\n */\nexport async function executeGroupMember(\n memberRuntime: GroupMemberRuntime,\n parentInput: unknown,\n ctx: StepContext,\n parentStepOutputs?: ReadonlyMap<string, unknown>,\n onStateChange?: () => void,\n): Promise<void> {\n memberRuntime.status = \"running\";\n memberRuntime.startedAt = Date.now();\n onStateChange?.();\n\n try {\n if (isSubgraphMember(memberRuntime.member)) {\n const subgraph = memberRuntime.member;\n\n // Wait for and resolve external dependencies from parent step outputs\n let injectedSteps: Map<string, unknown> | undefined;\n if (subgraph.externalDeps && parentStepOutputs) {\n const deps = Object.entries(subgraph.externalDeps);\n // Wait until all external dep parent steps have outputs\n while (\n !ctx.signal.aborted &&\n deps.some(([, parentName]) => !parentStepOutputs.has(parentName))\n ) {\n await new Promise((r) => setTimeout(r, 10));\n }\n injectedSteps = new Map();\n for (const [childStepName, parentStepName] of deps) {\n injectedSteps.set(\n childStepName,\n parentStepOutputs.get(parentStepName),\n );\n }\n }\n\n // Subgraph member: create a child FlowRun with injected external deps\n // Hook into child events to bubble state changes to parent\n const childHooks = onStateChange\n ? {\n onStepComplete: onStateChange,\n onStepError: onStateChange,\n onStepStart: onStateChange,\n }\n : undefined;\n const childRun = subgraph.flow.run({\n hooks: childHooks,\n injectedSteps,\n });\n memberRuntime.childRun = childRun;\n\n // Abort child if parent aborts\n const onAbort = (): void => childRun.abort();\n ctx.signal.addEventListener(\"abort\", onAbort);\n\n const result = await childRun.result;\n\n ctx.signal.removeEventListener(\"abort\", onAbort);\n\n if (result.status === \"error\") {\n // Find the first error step for the error message\n const errorStep = result.steps.find((s) => s.status === \"error\");\n throw new Error(errorStep?.error ?? \"Subgraph failed\");\n }\n\n // Output is the terminal step's output, or the last step's output\n const terminalStep = result.steps.find(\n (s) =>\n s.status === \"success\" &&\n subgraph.flow.steps.some(\n (d: { name: string; terminal: boolean }) =>\n d.name === s.name && d.terminal,\n ),\n );\n memberRuntime.output =\n terminalStep?.output ??\n result.steps.findLast((s) => s.status === \"success\")?.output;\n } else {\n const single = memberRuntime.member as SingleMember<unknown, unknown>;\n memberRuntime.output = await invokeHandler(\n single.execute,\n parentInput,\n ctx,\n );\n }\n memberRuntime.status = \"success\";\n memberRuntime.completedAt = Date.now();\n onStateChange?.();\n } catch (error) {\n memberRuntime.status = \"error\";\n memberRuntime.completedAt = Date.now();\n onStateChange?.();\n memberRuntime.error =\n error instanceof Error ? error.message : String(error);\n throw error;\n }\n}\n","export class History {\n private readonly store = new Map<string, unknown>();\n\n set(key: string, value: unknown): void {\n this.store.set(key, value);\n }\n\n get<T>(key: string): T | undefined {\n return this.store.get(key) as T | undefined;\n }\n\n has(key: string): boolean {\n return this.store.has(key);\n }\n\n snapshot(): ReadonlyMap<string, unknown> {\n return new Map(this.store);\n }\n}\n","import type { Flow } from \"./flow.js\";\nimport { type FlowSnapshot, createSnapshot } from \"./snapshot.js\";\nimport {\n getReadySteps,\n getReadyWithFailures,\n getSkippableSteps,\n} from \"./graph.js\";\nimport {\n type GroupRuntime,\n addGroupMembers,\n collectGroupOutputs,\n collectSuccessOutputs,\n createGroupRuntime,\n executeGroupMember,\n isGroupComplete,\n} from \"./group.js\";\nimport { History } from \"./history.js\";\nimport type {\n FlowHooks,\n FlowRunResult,\n GroupMember,\n RunHandle,\n RunOptions,\n RunStatus,\n StepContext,\n StepDefinition,\n StepHandler,\n StepRecord,\n StepResult,\n StepStatus,\n} from \"./types.js\";\nimport { invokeHandler } from \"./types.js\";\n\nconst generateRunId = (): string => crypto.randomUUID().slice(0, 8);\n\n/**\n * Runtime execution engine for a single flow run.\n * Uses wave-based scheduling: collect ready steps, launch concurrently,\n * await all, find newly ready steps, repeat.\n */\nexport class FlowRun<\n TRegistry extends Record<string, unknown> = Record<string, unknown>,\n> {\n readonly runId: string;\n private readonly flow: Flow<TRegistry>;\n private readonly hooks: FlowHooks;\n private readonly failFast: boolean;\n private readonly abortController: AbortController;\n\n private readonly history: History;\n private readonly stepDefs: Map<string, StepDefinition>;\n private readonly stepRecords: Map<string, StepRecord>;\n private readonly stepOutputs: Map<string, unknown>;\n\n private readonly groupRuntimes: Map<string, GroupRuntime>;\n private readonly providedSlots: Map<string, StepHandler<unknown, unknown>>;\n private readonly providedData: Map<string, unknown>;\n\n private status: RunStatus = \"idle\";\n private startedAt = 0;\n\n private resolveResult!: (result: FlowRunResult) => void;\n readonly result: Promise<FlowRunResult>;\n\n private loopRunning = false;\n private readonly pendingGroupStarts: GroupRuntime[] = [];\n private dynamicStepsAdded = false;\n\n constructor(flow: Flow<TRegistry>, options?: RunOptions) {\n this.runId = generateRunId();\n this.flow = flow;\n this.hooks = options?.hooks ?? {};\n this.failFast = options?.failFast ?? false;\n this.abortController = new AbortController();\n this.history = new History();\n\n this.stepDefs = new Map();\n this.stepRecords = new Map();\n this.stepOutputs = new Map();\n this.groupRuntimes = new Map();\n this.providedSlots = new Map();\n this.providedData = new Map();\n\n // Initialize step definitions from the flow\n for (const step of flow.steps) {\n this.stepDefs.set(step.name, step);\n this.stepRecords.set(step.name, {\n name: step.name,\n parentNames: step.parentNames,\n status: \"pending\",\n });\n }\n\n // Initialize group runtimes\n for (const group of flow.groups) {\n this.groupRuntimes.set(\n group.name,\n createGroupRuntime(group.name, group.dependsOn),\n );\n }\n\n // Inject pre-resolved steps (for cross-boundary subgraph deps)\n if (options?.injectedSteps) {\n for (const [name, output] of options.injectedSteps) {\n if (!this.stepDefs.has(name)) {\n // Create a synthetic step definition\n this.stepDefs.set(name, {\n allowFailures: false,\n handler: async () => output,\n name,\n parentNames: [],\n terminal: false,\n });\n }\n this.stepRecords.set(name, {\n completedAt: Date.now(),\n durationMs: 0,\n name,\n output,\n parentNames: [],\n startedAt: Date.now(),\n status: \"success\",\n });\n this.stepOutputs.set(name, output);\n }\n }\n\n this.result = new Promise((resolve) => {\n this.resolveResult = resolve;\n });\n\n // Start execution immediately\n this.startExecution();\n }\n\n /**\n * Read-only snapshot of current step records.\n */\n get steps(): readonly StepRecord[] {\n return Array.from(this.stepRecords.values());\n }\n\n /**\n * JSON-serializable snapshot of the current flow + run state.\n */\n snapshot(): FlowSnapshot {\n return createSnapshot({\n flow: this.flow,\n groupRuntimes: this.groupRuntimes,\n run: {\n completedAt: undefined,\n runId: this.runId,\n startedAt: this.startedAt,\n status: this.status,\n },\n stepRecords: this.stepRecords,\n });\n }\n\n /**\n * Abort the run — signals all in-progress steps.\n */\n abort(): void {\n this.abortController.abort();\n }\n\n /**\n * Add a step dynamically during execution.\n */\n addStep(def: StepDefinition): void {\n this.stepDefs.set(def.name, def);\n const record: StepRecord = {\n name: def.name,\n parentNames: def.parentNames,\n status: \"pending\",\n };\n this.stepRecords.set(def.name, record);\n this.fireHook(\"onStepAdded\", record);\n this.dynamicStepsAdded = true;\n\n // If the loop is idle, restart it\n if (!this.loopRunning && this.status === \"running\") {\n this.executionLoop();\n }\n }\n\n /**\n * Spawn members into a group and auto-seal it.\n */\n spawnGroup(groupName: string, members: readonly GroupMember[]): void {\n const grp = this.groupRuntimes.get(groupName);\n if (!grp) {\n throw new Error(`Unknown group \"${groupName}\"`);\n }\n addGroupMembers(grp, members, true);\n this.startOrDeferGroup(grp);\n }\n\n /**\n * Add a single member to a group (without sealing).\n */\n addGroupMember(groupName: string, member: GroupMember): void {\n const grp = this.groupRuntimes.get(groupName);\n if (!grp) {\n throw new Error(`Unknown group \"${groupName}\"`);\n }\n addGroupMembers(grp, [member], false);\n this.startOrDeferGroup(grp);\n }\n\n /**\n * Seal a group — no more members can be added.\n */\n sealGroup(groupName: string): void {\n const group = this.groupRuntimes.get(groupName);\n if (!group) {\n throw new Error(`Unknown group \"${groupName}\"`);\n }\n group.sealed = true;\n this.checkGroupCompletion(group);\n }\n\n /**\n * Provide a step implementation (slot fill) or external data.\n */\n provide(\n path: string,\n value: StepHandler<unknown, unknown> | Record<string, unknown> | unknown,\n ): void {\n if (typeof value === \"function\" || isExecutableValue(value)) {\n this.providedSlots.set(path, value as StepHandler<unknown, unknown>);\n } else {\n this.providedData.set(path, value);\n }\n }\n\n // --- Private helpers ---\n\n private createContext(): StepContext {\n const runHandle: RunHandle = {\n addGroupMember: (groupName, member) =>\n this.addGroupMember(groupName, member),\n provide: (path, value) => this.provide(path, value),\n sealGroup: (groupName) => this.sealGroup(groupName),\n spawnGroup: (groupName, members) => this.spawnGroup(groupName, members),\n };\n\n return {\n history: this.history,\n provided<T>(): T {\n return undefined as T;\n },\n run: runHandle,\n runId: this.runId,\n signal: this.abortController.signal,\n };\n }\n\n // --- Private execution logic ---\n\n private async startExecution(): Promise<void> {\n this.status = \"running\";\n this.startedAt = Date.now();\n await this.executionLoop();\n }\n\n private async executionLoop(): Promise<void> {\n if (this.loopRunning) return;\n this.loopRunning = true;\n\n try {\n while (!this.abortController.signal.aborted) {\n this.dynamicStepsAdded = false;\n\n // Mark skippable steps\n this.markSkippableSteps();\n\n // Collect ready steps (normal + allowFailures)\n const allDefs = Array.from(this.stepDefs.values());\n const statuses = this.getStatusMap();\n const readyNormal = getReadySteps(allDefs, statuses);\n const readyWithFailures = getReadyWithFailures(allDefs, statuses);\n const ready = [...new Set([...readyNormal, ...readyWithFailures])];\n\n if (ready.length === 0) {\n // Check if there are still running steps (from groups etc.)\n const hasRunning = Array.from(this.stepRecords.values()).some(\n (r) => r.status === \"running\",\n );\n const hasPendingGroups = Array.from(this.groupRuntimes.values()).some(\n (g) => !isGroupComplete(g) && g.members.length > 0,\n );\n\n if (!hasRunning && !hasPendingGroups && !this.dynamicStepsAdded) {\n break;\n }\n\n // Wait a tick for dynamic steps or group completions\n if (!this.dynamicStepsAdded) {\n await new Promise((resolve) => setTimeout(resolve, 1));\n continue;\n }\n continue;\n }\n\n // Launch ready steps concurrently — each completion re-triggers the loop\n // so dependent steps start immediately, not after the whole wave settles\n await new Promise<void>((resolveWave) => {\n let pending = ready.length;\n for (const name of ready) {\n this.executeStep(name).finally(() => {\n pending--;\n\n if (this.failFast && this.hasAnyError()) {\n this.abortController.abort();\n }\n\n // Re-check for newly ready steps after each completion\n this.scheduleReadySteps();\n\n if (pending === 0) resolveWave();\n });\n }\n });\n }\n } finally {\n this.loopRunning = false;\n }\n\n this.completeRun();\n }\n\n /**\n * Check for and launch any newly ready steps without waiting for the full wave.\n * Called after each individual step completion.\n */\n private scheduleReadySteps(): void {\n this.markSkippableSteps();\n this.flushPendingGroups();\n\n const allDefs = Array.from(this.stepDefs.values());\n const statuses = this.getStatusMap();\n const readyNormal = getReadySteps(allDefs, statuses);\n const readyWithFailures = getReadyWithFailures(allDefs, statuses);\n const ready = [...new Set([...readyNormal, ...readyWithFailures])];\n\n for (const name of ready) {\n this.executeStep(name).finally(() => {\n this.scheduleReadySteps();\n });\n }\n }\n\n private async executeStep(name: string): Promise<void> {\n const def = this.stepDefs.get(name)!;\n const record = this.stepRecords.get(name)!;\n\n // Mark as running\n (record as { status: StepStatus }).status = \"running\";\n (record as { startedAt: number }).startedAt = Date.now();\n this.fireHook(\"onStepStart\", record);\n\n try {\n // Build input from parent outputs\n const input = this.buildInput(def);\n\n const ctx = this.createContext();\n\n const output = await invokeHandler(def.handler, input, ctx);\n\n (record as { status: StepStatus }).status = \"success\";\n (record as { completedAt: number }).completedAt = Date.now();\n (record as { durationMs: number }).durationMs =\n record.completedAt! - record.startedAt!;\n (record as { output: unknown }).output = output;\n this.stepOutputs.set(name, output);\n\n this.fireHook(\"onStepComplete\", record);\n this.flushPendingGroups();\n } catch (error) {\n (record as { status: StepStatus }).status = \"error\";\n (record as { completedAt: number }).completedAt = Date.now();\n (record as { durationMs: number }).durationMs =\n record.completedAt! - record.startedAt!;\n (record as { error: string }).error =\n error instanceof Error ? error.message : String(error);\n\n this.fireHook(\"onStepError\", record);\n }\n }\n\n private buildInput(def: StepDefinition): unknown {\n const input: Record<string, unknown> = {};\n\n for (const parentName of def.parentNames) {\n // Check if it's a group\n const groupRuntime = this.groupRuntimes.get(parentName);\n if (groupRuntime) {\n input[parentName] = def.allowFailures\n ? collectGroupOutputs(groupRuntime)\n : collectSuccessOutputs(groupRuntime);\n continue;\n }\n\n // Regular step parent\n if (def.allowFailures) {\n const parentRecord = this.stepRecords.get(parentName);\n if (parentRecord?.status === \"success\") {\n input[parentName] = {\n status: \"success\",\n value: this.stepOutputs.get(parentName),\n } satisfies StepResult<unknown>;\n } else if (parentRecord?.status === \"error\") {\n input[parentName] = {\n error: parentRecord.error ?? \"Unknown error\",\n status: \"error\",\n } satisfies StepResult<unknown>;\n } else {\n input[parentName] = {\n status: \"skipped\",\n } satisfies StepResult<unknown>;\n }\n } else {\n input[parentName] = this.stepOutputs.get(parentName);\n }\n }\n\n if (def.transform) {\n return def.transform(input);\n }\n\n return input;\n }\n\n private markSkippableSteps(): void {\n const allDefs = Array.from(this.stepDefs.values());\n const statuses = this.getStatusMap();\n let changed = true;\n\n while (changed) {\n changed = false;\n const skippable = getSkippableSteps(allDefs, statuses);\n for (const name of skippable) {\n const record = this.stepRecords.get(name)!;\n (record as { status: StepStatus }).status = \"skipped\";\n statuses.set(name, \"skipped\");\n changed = true;\n }\n }\n }\n\n private getStatusMap(): Map<string, StepStatus> {\n const map = new Map<string, StepStatus>();\n for (const [name, record] of this.stepRecords) {\n map.set(name, record.status);\n }\n // Groups appear as step-like nodes\n for (const [name, group] of this.groupRuntimes) {\n if (isGroupComplete(group)) {\n const allSuccess = group.members.every((m) => m.status === \"success\");\n map.set(name, allSuccess ? \"success\" : \"error\");\n } else if (group.members.some((m) => m.status === \"running\")) {\n map.set(name, \"running\");\n } else if (group.members.length > 0) {\n map.set(name, \"running\");\n } else {\n map.set(name, \"pending\");\n }\n }\n return map;\n }\n\n private hasAnyError(): boolean {\n for (const record of this.stepRecords.values()) {\n if (record.status === \"error\") return true;\n }\n return false;\n }\n\n private areGroupDependenciesMet(group: GroupRuntime): boolean {\n for (const dep of group.dependsOn) {\n const record = this.stepRecords.get(dep);\n if (!record || record.status !== \"success\") return false;\n }\n return true;\n }\n\n private startOrDeferGroup(grp: GroupRuntime): void {\n if (this.areGroupDependenciesMet(grp)) {\n this.startGroupMembers(grp);\n } else {\n // Defer — will be flushed after the currently-executing step completes\n if (!this.pendingGroupStarts.includes(grp)) {\n this.pendingGroupStarts.push(grp);\n }\n }\n }\n\n private flushPendingGroups(): void {\n const toFlush = [...this.pendingGroupStarts];\n this.pendingGroupStarts.length = 0;\n for (const grp of toFlush) {\n if (this.areGroupDependenciesMet(grp)) {\n this.startGroupMembers(grp);\n } else {\n // Still not ready — re-defer\n this.pendingGroupStarts.push(grp);\n }\n }\n }\n\n private startGroupMembers(group: GroupRuntime): void {\n if (!this.areGroupDependenciesMet(group)) return;\n\n // Build parent input from group dependencies\n const parentInput: Record<string, unknown> = {};\n for (const dep of group.dependsOn) {\n parentInput[dep] = this.stepOutputs.get(dep);\n }\n\n const ctx = this.createContext();\n\n for (const member of group.members) {\n if (member.status !== \"pending\") continue;\n\n executeGroupMember(member, parentInput, ctx, this.stepOutputs, () =>\n this.fireHook(\"onChange\", undefined),\n )\n .then(() => {\n this.checkGroupCompletion(group);\n })\n .catch(() => {\n this.checkGroupCompletion(group);\n });\n }\n }\n\n private checkGroupCompletion(group: GroupRuntime): void {\n if (isGroupComplete(group)) {\n // Signal dynamic step addition to wake the loop\n this.dynamicStepsAdded = true;\n this.fireHook(\"onChange\", undefined);\n }\n }\n\n private completeRun(): void {\n // Determine final status\n const terminalSteps = Array.from(this.stepDefs.values()).filter(\n (d) => d.terminal,\n );\n const stepsToCheck =\n terminalSteps.length > 0\n ? terminalSteps.map((d) => this.stepRecords.get(d.name)!)\n : Array.from(this.stepRecords.values());\n\n const hasError = stepsToCheck.some((r) => r.status === \"error\");\n this.status = hasError ? \"error\" : \"success\";\n\n const result: FlowRunResult = {\n completedAt: Date.now(),\n history: this.history.snapshot(),\n runId: this.runId,\n startedAt: this.startedAt,\n status: this.status,\n steps: Array.from(this.stepRecords.values()),\n };\n\n this.fireHook(\"onRunComplete\", result);\n this.resolveResult(result);\n }\n\n private fireHook(\n hookName: keyof FlowHooks,\n arg?: StepRecord | FlowRunResult | undefined,\n ): void {\n try {\n const hook = this.hooks[hookName];\n if (hook) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (hook as (...args: any[]) => void)(arg);\n }\n // Also fire onChange for any event\n if (hookName !== \"onChange\" && this.hooks.onChange) {\n this.hooks.onChange();\n }\n } catch {\n // Hooks should not break execution\n }\n }\n}\n\nfunction isExecutableValue(value: unknown): boolean {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"execute\" in value &&\n typeof (value as Record<string, unknown>).execute === \"function\"\n );\n}\n","import { validateAcyclic } from \"./graph.js\";\nimport { FlowRun } from \"./flow-run.js\";\nimport type { GroupDefinition, RunOptions, StepDefinition } from \"./types.js\";\n\n/**\n * Immutable DAG blueprint produced by FlowBuilder.build().\n * Call .run() to create execution instances.\n */\nexport class Flow<\n TRegistry extends Record<string, unknown> = Record<string, unknown>,\n> {\n readonly name: string;\n readonly steps: readonly StepDefinition[];\n readonly groups: readonly GroupDefinition[];\n\n constructor(\n name: string,\n steps: StepDefinition[],\n groups: GroupDefinition[],\n ) {\n // Validate the DAG at build time — include groups as graph nodes\n const groupNodes = groups.map((g) => ({\n name: g.name,\n parentNames: g.dependsOn,\n }));\n validateAcyclic([...steps, ...groupNodes]);\n\n this.name = name;\n this.steps = Object.freeze([...steps]);\n this.groups = Object.freeze([...groups]);\n }\n\n /**\n * Creates a new FlowRun instance.\n * Multiple runs can execute concurrently from the same Flow.\n */\n run(options?: RunOptions): FlowRun<TRegistry> {\n return new FlowRun<TRegistry>(this, options);\n }\n}\n","import { DuplicateStepError, UnknownParentError } from \"./errors.js\";\nimport { Flow } from \"./flow.js\";\nimport type {\n GroupDefinition,\n GroupRef,\n StepDefinition,\n StepHandler,\n StepOptions,\n} from \"./types.js\";\nimport { isGroupRef } from \"./types.js\";\n\n/**\n * Chainable builder for constructing type-safe flow graphs.\n *\n * Each `.step()` call returns a new FlowBuilder with an expanded registry.\n * Positional arguments allow TypeScript to infer literal string types\n * without needing `as const`.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport class FlowBuilder<TRegistry extends Record<string, unknown> = {}> {\n private readonly flowName: string;\n private readonly steps: StepDefinition[];\n private readonly groups: GroupDefinition[];\n private readonly knownNames: Set<string>;\n\n constructor(\n flowName: string,\n steps: StepDefinition[] = [],\n groups: GroupDefinition[] = [],\n knownNames?: Set<string>,\n ) {\n this.flowName = flowName;\n this.steps = steps;\n this.groups = groups;\n this.knownNames = knownNames ?? new Set(steps.map((s) => s.name));\n }\n\n /**\n * Root step — no parents.\n * .step(\"name\", executeFn)\n * .step(\"name\", executableInstance)\n */\n step<TName extends string, TOutput>(\n name: TName,\n handler: StepHandler<Record<string, unknown>, TOutput>,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with parents — input auto-derived from parent outputs.\n * .step(\"name\", [\"parent1\", \"parent2\"], executeFn)\n */\n step<\n TName extends string,\n TParents extends readonly (keyof TRegistry & string)[],\n TOutput,\n >(\n name: TName,\n parents: [...TParents],\n handler: StepHandler<{ [K in TParents[number]]: TRegistry[K] }, TOutput>,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with parents + options object.\n * .step(\"name\", [\"parent1\"], { execute, transform?, allowFailures?, terminal? })\n */\n step<\n TName extends string,\n TParents extends readonly (keyof TRegistry & string)[],\n TOutput,\n >(\n name: TName,\n parents: [...TParents],\n options: StepOptions<{ [K in TParents[number]]: TRegistry[K] }, TOutput>,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with group ref dependencies.\n * .step(\"name\", [group(\"reviews\")], executeFn)\n */\n step<TName extends string, TDeps extends readonly unknown[], TOutput>(\n name: TName,\n deps: [...TDeps],\n handler:\n | StepHandler<\n {\n [K in TDeps[number] as K extends string\n ? K\n : K extends GroupRef<infer G>\n ? G\n : never]: K extends string\n ? TRegistry[K & keyof TRegistry]\n : K extends GroupRef<infer G>\n ? TRegistry[G & keyof TRegistry]\n : never;\n },\n TOutput\n >\n | StepOptions<\n {\n [K in TDeps[number] as K extends string\n ? K\n : K extends GroupRef<infer G>\n ? G\n : never]: K extends string\n ? TRegistry[K & keyof TRegistry]\n : K extends GroupRef<infer G>\n ? TRegistry[G & keyof TRegistry]\n : never;\n },\n TOutput\n >,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n // Implementation\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n step(name: string, parentsOrHandler: any, handlerOrOptions?: any): any {\n if (this.knownNames.has(name)) {\n throw new DuplicateStepError(name);\n }\n\n let parentNames: string[] = [];\n let handler: StepHandler<unknown, unknown>;\n let allowFailures = false;\n let terminal = false;\n let transform: ((input: unknown) => unknown) | undefined;\n\n if (Array.isArray(parentsOrHandler)) {\n // .step(name, parents, handler/options)\n parentNames = parentsOrHandler.map((p: unknown) => {\n if (isGroupRef(p)) return p.groupName;\n return p as string;\n });\n if (\n typeof handlerOrOptions === \"object\" &&\n handlerOrOptions !== null &&\n \"execute\" in handlerOrOptions\n ) {\n const opts = handlerOrOptions as StepOptions<unknown, unknown>;\n handler = opts.execute;\n allowFailures = opts.allowFailures ?? false;\n terminal = opts.terminal ?? false;\n transform = opts.transform as ((input: unknown) => unknown) | undefined;\n } else {\n handler = handlerOrOptions as StepHandler<unknown, unknown>;\n }\n } else {\n // .step(name, handler) — root step\n handler = parentsOrHandler as StepHandler<unknown, unknown>;\n }\n\n // Validate parents exist\n for (const parent of parentNames) {\n if (!this.knownNames.has(parent)) {\n throw new UnknownParentError(name, parent);\n }\n }\n\n const newSteps = [\n ...this.steps,\n {\n allowFailures,\n handler,\n name,\n parentNames,\n terminal,\n transform,\n } satisfies StepDefinition,\n ];\n const newKnown = new Set(this.knownNames);\n newKnown.add(name);\n\n return new FlowBuilder(this.flowName, newSteps, [...this.groups], newKnown);\n }\n\n /**\n * Declare a typed group for dynamic fan-in.\n * .group<TOut>(\"reviews\", { dependsOn: [\"arbiter\"] })\n */\n group<TOut, TName extends string = string>(\n name: TName,\n options: { dependsOn?: (keyof TRegistry & string)[] } = {},\n ): FlowBuilder<TRegistry & Record<TName, TOut[]>> {\n if (this.knownNames.has(name)) {\n throw new DuplicateStepError(name);\n }\n\n const dependsOn = options.dependsOn ?? [];\n for (const dep of dependsOn) {\n if (!this.knownNames.has(dep)) {\n throw new UnknownParentError(name, dep);\n }\n }\n\n const newGroups = [...this.groups, { dependsOn, name }];\n const newKnown = new Set(this.knownNames);\n newKnown.add(name);\n\n return new FlowBuilder(\n this.flowName,\n [...this.steps],\n newGroups,\n newKnown,\n ) as FlowBuilder<TRegistry & Record<typeof name, TOut[]>>;\n }\n\n /**\n * Validates the DAG and returns an immutable Flow.\n */\n build(): Flow<TRegistry> {\n return new Flow<TRegistry>(this.flowName, this.steps, this.groups);\n }\n}\n\n/**\n * Entry point: creates a new FlowBuilder.\n */\nexport function flow(name: string): FlowBuilder {\n return new FlowBuilder(name);\n}\n","import { flow as flowBuilder } from \"./flow-builder.js\";\nimport type { StepHandler, SubgraphMember } from \"./types.js\";\n\nexport interface PipelineStepDef {\n execute?: StepHandler<unknown, unknown>;\n name: string;\n}\n\n/**\n * Convenience builder that creates a SubgraphMember with a linear DAG.\n * Each step depends on the previous one, forming a sequential pipeline.\n *\n * ```typescript\n * pipeline(\"tone-analysis\", [\n * { name: \"detect\", execute: detectFn },\n * { name: \"classify\", execute: classifyFn },\n * { name: \"score\", execute: scoreFn },\n * ])\n * ```\n *\n * is equivalent to building a flow:\n * detect → classify → score (terminal)\n */\nexport function pipeline(\n name: string,\n steps: PipelineStepDef[],\n): SubgraphMember {\n if (steps.length === 0) {\n throw new Error(`Pipeline \"${name}\" must have at least one step`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let builder: any = flowBuilder(`${name}`);\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n const handler = step.execute ?? (async (input: unknown) => input);\n const isLast = i === steps.length - 1;\n\n if (i === 0) {\n // Root step — no parents\n builder = isLast\n ? builder.step(step.name, {\n execute: handler,\n terminal: true,\n })\n : builder.step(step.name, handler);\n } else {\n // Chain: depends on previous step\n const parents = [steps[i - 1]!.name];\n builder = isLast\n ? builder.step(step.name, parents, {\n execute: handler,\n terminal: true,\n })\n : builder.step(step.name, parents, handler);\n }\n }\n\n return { flow: builder.build(), name };\n}\n"],"mappings":"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","names":["group","flow","group"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/graph.ts","../src/types.ts","../src/snapshot.ts","../src/group.ts","../src/history.ts","../src/flow-run.ts","../src/flow.ts","../src/flow-builder.ts","../src/pipeline.ts"],"sourcesContent":["export class CycleDetectedError extends Error {\n constructor(cycle: string[]) {\n super(`Cycle detected in flow graph: ${cycle.join(\" → \")}`);\n this.name = \"CycleDetectedError\";\n }\n}\n\nexport class DuplicateStepError extends Error {\n constructor(name: string) {\n super(`Step \"${name}\" is already registered`);\n this.name = \"DuplicateStepError\";\n }\n}\n\nexport class UnknownParentError extends Error {\n constructor(stepName: string, parentName: string) {\n super(`Step \"${stepName}\" depends on unknown parent \"${parentName}\"`);\n this.name = \"UnknownParentError\";\n }\n}\n\nexport class UnsealedGroupError extends Error {\n constructor(groupName: string) {\n super(`Group \"${groupName}\" was never sealed`);\n this.name = \"UnsealedGroupError\";\n }\n}\n\nexport class UnfilledSlotError extends Error {\n constructor(slotPath: string) {\n super(`Slot \"${slotPath}\" was not provided an implementation`);\n this.name = \"UnfilledSlotError\";\n }\n}\n\nexport class StepExecutionError extends Error {\n readonly stepName: string;\n readonly cause: unknown;\n\n constructor(stepName: string, cause: unknown) {\n const message = cause instanceof Error ? cause.message : String(cause);\n super(`Step \"${stepName}\" failed: ${message}`);\n this.name = \"StepExecutionError\";\n this.stepName = stepName;\n this.cause = cause;\n }\n}\n","import { CycleDetectedError } from \"./errors.js\";\nimport type { StepDefinition, StepStatus } from \"./types.js\";\n\nexport interface GraphNode {\n readonly name: string;\n readonly parentNames: readonly string[];\n}\n\n/**\n * Validates that the graph has no cycles using Kahn's algorithm.\n * Throws CycleDetectedError if a cycle is found.\n */\nexport function validateAcyclic(nodes: readonly GraphNode[]): void {\n const inDegree = new Map<string, number>();\n const children = new Map<string, string[]>();\n\n for (const node of nodes) {\n if (!inDegree.has(node.name)) {\n inDegree.set(node.name, 0);\n }\n if (!children.has(node.name)) {\n children.set(node.name, []);\n }\n for (const parent of node.parentNames) {\n if (!children.has(parent)) {\n children.set(parent, []);\n }\n children.get(parent)!.push(node.name);\n inDegree.set(node.name, (inDegree.get(node.name) ?? 0) + 1);\n }\n }\n\n const queue: string[] = [];\n for (const [name, degree] of inDegree) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n let visited = 0;\n while (queue.length > 0) {\n const current = queue.shift()!;\n visited++;\n for (const child of children.get(current) ?? []) {\n const newDegree = inDegree.get(child)! - 1;\n inDegree.set(child, newDegree);\n if (newDegree === 0) {\n queue.push(child);\n }\n }\n }\n\n if (visited < nodes.length) {\n const remaining = nodes\n .filter((n) => (inDegree.get(n.name) ?? 0) > 0)\n .map((n) => n.name);\n throw new CycleDetectedError(remaining);\n }\n}\n\n/**\n * Returns a valid topological ordering of the nodes.\n * Assumes the graph is acyclic (call validateAcyclic first).\n */\nexport function topologicalSort(nodes: readonly GraphNode[]): string[] {\n const inDegree = new Map<string, number>();\n const children = new Map<string, string[]>();\n\n for (const node of nodes) {\n if (!inDegree.has(node.name)) {\n inDegree.set(node.name, 0);\n }\n if (!children.has(node.name)) {\n children.set(node.name, []);\n }\n for (const parent of node.parentNames) {\n if (!children.has(parent)) {\n children.set(parent, []);\n }\n children.get(parent)!.push(node.name);\n inDegree.set(node.name, (inDegree.get(node.name) ?? 0) + 1);\n }\n }\n\n const queue: string[] = [];\n for (const [name, degree] of inDegree) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n const sorted: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift()!;\n sorted.push(current);\n for (const child of children.get(current) ?? []) {\n const newDegree = inDegree.get(child)! - 1;\n inDegree.set(child, newDegree);\n if (newDegree === 0) {\n queue.push(child);\n }\n }\n }\n\n return sorted;\n}\n\n/**\n * Returns names of steps that are ready to execute:\n * all parents have completed with \"success\" status.\n */\nexport function getReadySteps(\n steps: readonly GraphNode[],\n statuses: ReadonlyMap<string, StepStatus>,\n): string[] {\n const ready: string[] = [];\n\n for (const step of steps) {\n const status = statuses.get(step.name);\n if (status !== \"pending\") continue;\n\n const allParentsDone = step.parentNames.every((parent) => {\n const parentStatus = statuses.get(parent);\n return parentStatus === \"success\";\n });\n\n if (allParentsDone) {\n ready.push(step.name);\n }\n }\n\n return ready;\n}\n\n/**\n * Returns names of steps that should be skipped because\n * at least one parent has \"error\" or \"skipped\" status\n * and the step does NOT have allowFailures set.\n */\nexport function getSkippableSteps(\n steps: readonly StepDefinition[],\n statuses: ReadonlyMap<string, StepStatus>,\n): string[] {\n const skippable: string[] = [];\n\n for (const step of steps) {\n const status = statuses.get(step.name);\n if (status !== \"pending\") continue;\n if (step.allowFailures) continue;\n\n const hasFailedParent = step.parentNames.some((parent) => {\n const parentStatus = statuses.get(parent);\n return parentStatus === \"error\" || parentStatus === \"skipped\";\n });\n\n if (hasFailedParent) {\n skippable.push(step.name);\n }\n }\n\n return skippable;\n}\n\n/**\n * Returns names of steps with allowFailures that are ready to execute:\n * all parents have completed (success, error, or skipped).\n */\nexport function getReadyWithFailures(\n steps: readonly StepDefinition[],\n statuses: ReadonlyMap<string, StepStatus>,\n): string[] {\n const ready: string[] = [];\n\n for (const step of steps) {\n const status = statuses.get(step.name);\n if (status !== \"pending\") continue;\n if (!step.allowFailures) continue;\n\n const allParentsSettled = step.parentNames.every((parent) => {\n const parentStatus = statuses.get(parent);\n return (\n parentStatus === \"success\" ||\n parentStatus === \"error\" ||\n parentStatus === \"skipped\"\n );\n });\n\n if (allParentsSettled) {\n ready.push(step.name);\n }\n }\n\n return ready;\n}\n","import type { History } from \"./history.js\";\n\n// --- Status types ---\n\nexport type StepStatus =\n | \"pending\"\n | \"running\"\n | \"success\"\n | \"error\"\n | \"skipped\";\n\nexport type RunStatus = \"idle\" | \"running\" | \"success\" | \"error\";\n\n// --- Step result (for allowFailures) ---\n\nexport type StepResult<T> =\n | { status: \"success\"; value: T }\n | { error: string; status: \"error\" }\n | { status: \"skipped\" };\n\n// --- Run handle (exposed to steps via context) ---\n\nexport interface RunHandle {\n addGroupMember(groupName: string, member: GroupMember): void;\n provide(path: string, value: unknown): void;\n sealGroup(groupName: string): void;\n spawnGroup(groupName: string, members: readonly GroupMember[]): void;\n}\n\n// --- Context ---\n\nexport interface StepContext {\n readonly history: History;\n provided<T>(): T;\n readonly run: RunHandle;\n readonly runId: string;\n readonly signal: AbortSignal;\n}\n\n// --- Executable interface ---\n\nexport interface Executable<TInput, TOutput> {\n execute(input: TInput, ctx: StepContext): Promise<TOutput>;\n}\n\n// --- Step handler union ---\n\nexport type StepHandler<TInput, TOutput> =\n | ((input: TInput, ctx: StepContext) => Promise<TOutput>)\n | Executable<TInput, TOutput>;\n\n// --- Input mapper ---\n\nexport type InputMapper<TParentOutputs, TMapped> = (\n parentOutputs: TParentOutputs,\n) => TMapped;\n\n// --- Step options ---\n\nexport interface StepOptions<TInput, TOutput> {\n allowFailures?: boolean;\n execute: StepHandler<TInput, TOutput>;\n terminal?: boolean;\n transform?: (parentOutputs: unknown) => TInput;\n}\n\n// --- Step definition (internal) ---\n\nexport interface StepDefinition {\n readonly allowFailures: boolean;\n readonly handler: StepHandler<unknown, unknown>;\n readonly name: string;\n readonly parentNames: readonly string[];\n readonly terminal: boolean;\n readonly transform?: (parentOutputs: unknown) => unknown;\n}\n\n// --- Group definition (internal) ---\n\nexport interface GroupDefinition {\n readonly dependsOn: readonly string[];\n readonly name: string;\n}\n\n// --- Step record (runtime) ---\n\nexport interface StepRecord {\n completedAt?: number;\n durationMs?: number;\n error?: string;\n readonly name: string;\n output?: unknown;\n readonly parentNames: readonly string[];\n startedAt?: number;\n status: StepStatus;\n}\n\n// --- Run result ---\n\nexport interface FlowRunResult {\n readonly completedAt: number;\n readonly history: ReadonlyMap<string, unknown>;\n readonly runId: string;\n readonly startedAt: number;\n readonly status: RunStatus;\n readonly steps: readonly StepRecord[];\n}\n\n// --- Hooks ---\n\nexport interface FlowHooks {\n onChange?: () => void;\n onRunComplete?: (result: FlowRunResult) => void;\n onStepAdded?: (step: StepRecord) => void;\n onStepComplete?: (step: StepRecord) => void;\n onStepError?: (step: StepRecord) => void;\n onStepStart?: (step: StepRecord) => void;\n}\n\n// --- Run options ---\n\nexport interface RunOptions {\n failFast?: boolean;\n hooks?: FlowHooks;\n injectedSteps?: Map<string, unknown>;\n}\n\n// --- Group ref marker ---\n\nconst GROUP_REF_BRAND = Symbol(\"GroupRef\");\n\nexport interface GroupRef<K extends string> {\n readonly [GROUP_REF_BRAND]: true;\n readonly groupName: K;\n}\n\nexport function group<K extends string>(name: K): GroupRef<K> {\n return { [GROUP_REF_BRAND]: true, groupName: name } as GroupRef<K>;\n}\n\nexport function isGroupRef(value: unknown): value is GroupRef<string> {\n return (\n typeof value === \"object\" && value !== null && GROUP_REF_BRAND in value\n );\n}\n\n// --- Type-level utilities ---\n\nexport type ParentOutputs<\n TRegistry extends Record<string, unknown>,\n TParents extends readonly (keyof TRegistry & string)[],\n> = { [K in TParents[number]]: TRegistry[K] };\n\n/**\n * Resolves a mixed dependency array (step names + group refs) to their types.\n */\nexport type ResolveInput<\n TRegistry extends Record<string, unknown>,\n TDeps extends readonly unknown[],\n> = {\n [K in TDeps[number] as K extends string\n ? K\n : K extends GroupRef<infer G>\n ? G\n : never]: K extends string\n ? TRegistry[K]\n : K extends GroupRef<infer G>\n ? TRegistry[G]\n : never;\n};\n\n// --- Group member types ---\n\nexport interface SingleMember<TInput, TOutput> {\n readonly execute: StepHandler<TInput, TOutput>;\n readonly name: string;\n}\n\nexport interface SubgraphMember {\n readonly externalDeps?: Record<string, string>;\n readonly flow: import(\"./flow.js\").Flow;\n readonly name: string;\n}\n\nexport type GroupMember = SingleMember<unknown, unknown> | SubgraphMember;\n\nexport function isSubgraphMember(\n member: GroupMember,\n): member is SubgraphMember {\n return \"flow\" in member;\n}\n\n// --- Handler detection ---\n\nexport function isExecutable(\n value: unknown,\n): value is Executable<unknown, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"execute\" in value &&\n typeof (value as Record<string, unknown>).execute === \"function\"\n );\n}\n\nexport function invokeHandler<TInput, TOutput>(\n handler: StepHandler<TInput, TOutput>,\n input: TInput,\n ctx: StepContext,\n): Promise<TOutput> {\n if (isExecutable(handler)) {\n return handler.execute(input, ctx);\n }\n return (handler as (input: TInput, ctx: StepContext) => Promise<TOutput>)(\n input,\n ctx,\n );\n}\n","import type { GroupMemberRuntime, GroupRuntime } from \"./group.js\";\nimport type { RunStatus, StepStatus } from \"./types.js\";\nimport { isSubgraphMember } from \"./types.js\";\n\n// --- Snapshot types (JSON-serializable) ---\n\nexport interface FlowSnapshot {\n flow: {\n groups: FlowSnapshotGroup[];\n name: string;\n steps: FlowSnapshotStep[];\n };\n run: {\n completedAt?: number;\n runId: string;\n startedAt: number;\n status: RunStatus;\n };\n}\n\nexport interface FlowSnapshotStep {\n allowFailures: boolean;\n completedAt?: number;\n durationMs?: number;\n error?: string;\n name: string;\n output?: unknown;\n parentNames: string[];\n startedAt?: number;\n status: StepStatus;\n terminal: boolean;\n}\n\nexport interface FlowSnapshotGroup {\n dependsOn: string[];\n members: FlowSnapshotGroupMember[];\n name: string;\n sealed: boolean;\n}\n\nexport interface FlowSnapshotGroupMember {\n completedAt?: number;\n durationMs?: number;\n error?: string;\n externalDeps?: Record<string, string>;\n name: string;\n output?: unknown;\n startedAt?: number;\n status: \"pending\" | \"running\" | \"success\" | \"error\";\n subgraph?: FlowSnapshot;\n type: \"single\" | \"subgraph\";\n}\n\n// --- Snapshot creation ---\n\nexport interface SnapshotInput {\n flow: {\n groups: ReadonlyArray<{ dependsOn: readonly string[]; name: string }>;\n name: string;\n steps: ReadonlyArray<{\n allowFailures: boolean;\n name: string;\n parentNames: readonly string[];\n terminal: boolean;\n }>;\n };\n groupRuntimes: ReadonlyMap<string, GroupRuntime>;\n run: {\n completedAt?: number;\n runId: string;\n startedAt: number;\n status: RunStatus;\n };\n stepRecords: ReadonlyMap<\n string,\n {\n completedAt?: number;\n durationMs?: number;\n error?: string;\n name: string;\n output?: unknown;\n parentNames: readonly string[];\n startedAt?: number;\n status: StepStatus;\n }\n >;\n}\n\nexport function createSnapshot(input: SnapshotInput): FlowSnapshot {\n const steps: FlowSnapshotStep[] = input.flow.steps.map((def) => {\n const record = input.stepRecords.get(def.name);\n return {\n allowFailures: def.allowFailures,\n completedAt: record?.completedAt,\n durationMs: record?.durationMs,\n error: record?.error,\n name: def.name,\n output: record?.output,\n parentNames: [...def.parentNames],\n startedAt: record?.startedAt,\n status: record?.status ?? \"pending\",\n terminal: def.terminal,\n };\n });\n\n const groups: FlowSnapshotGroup[] = input.flow.groups.map((groupDef) => {\n const runtime = input.groupRuntimes.get(groupDef.name);\n return {\n dependsOn: [...groupDef.dependsOn],\n members: runtime?.members.map(serializeGroupMember) ?? [],\n name: groupDef.name,\n sealed: runtime?.sealed ?? false,\n };\n });\n\n return {\n flow: {\n groups,\n name: input.flow.name,\n steps,\n },\n run: {\n completedAt: input.run.completedAt,\n runId: input.run.runId,\n startedAt: input.run.startedAt,\n status: input.run.status,\n },\n };\n}\n\nfunction serializeGroupMember(\n member: GroupMemberRuntime,\n): FlowSnapshotGroupMember {\n const isSubgraph = isSubgraphMember(member.member);\n const durationMs =\n member.startedAt && member.completedAt\n ? member.completedAt - member.startedAt\n : undefined;\n\n const result: FlowSnapshotGroupMember = {\n completedAt: member.completedAt,\n durationMs,\n error: member.error,\n name: member.name,\n output: member.output,\n startedAt: member.startedAt,\n status: member.status,\n type: isSubgraph ? \"subgraph\" : \"single\",\n };\n\n if (isSubgraph) {\n const sub = member.member as import(\"./types.js\").SubgraphMember;\n if (sub.externalDeps) {\n result.externalDeps = { ...sub.externalDeps };\n }\n if (member.childRun) {\n result.subgraph = member.childRun.snapshot();\n }\n }\n\n return result;\n}\n","import type { FlowRun } from \"./flow-run.js\";\nimport {\n type GroupMember,\n type SingleMember,\n type StepContext,\n type StepResult,\n invokeHandler,\n isSubgraphMember,\n} from \"./types.js\";\n\nexport interface GroupRuntime {\n readonly dependsOn: readonly string[];\n readonly members: GroupMemberRuntime[];\n readonly name: string;\n sealed: boolean;\n}\n\nexport interface GroupMemberRuntime {\n childRun?: FlowRun;\n completedAt?: number;\n error?: string;\n readonly member: GroupMember;\n readonly name: string;\n output?: unknown;\n startedAt?: number;\n status: \"pending\" | \"running\" | \"success\" | \"error\";\n}\n\n/**\n * Creates a new runtime group tracker.\n */\nexport function createGroupRuntime(\n name: string,\n dependsOn: readonly string[],\n): GroupRuntime {\n return {\n dependsOn,\n members: [],\n name,\n sealed: false,\n };\n}\n\n/**\n * Adds members to a group and optionally seals it.\n */\nexport function addGroupMembers(\n group: GroupRuntime,\n members: readonly GroupMember[],\n seal: boolean,\n): void {\n for (const member of members) {\n group.members.push({\n member,\n name: member.name,\n status: \"pending\",\n });\n }\n if (seal) {\n group.sealed = true;\n }\n}\n\n/**\n * Checks if a group is complete (sealed + all members done).\n */\nexport function isGroupComplete(group: GroupRuntime): boolean {\n if (!group.sealed) return false;\n return group.members.every(\n (m) => m.status === \"success\" || m.status === \"error\",\n );\n}\n\n/**\n * Collects outputs from all group members.\n * Returns StepResult[] for allowFailures consumers, or the raw values.\n */\nexport function collectGroupOutputs(\n group: GroupRuntime,\n): StepResult<unknown>[] {\n return group.members.map((m) => {\n if (m.status === \"success\") {\n return { status: \"success\" as const, value: m.output };\n }\n return {\n error: m.error ?? \"Unknown error\",\n status: \"error\" as const,\n };\n });\n}\n\n/**\n * Collects only successful outputs (for non-allowFailures consumers).\n */\nexport function collectSuccessOutputs(group: GroupRuntime): unknown[] {\n return group.members\n .filter((m) => m.status === \"success\")\n .map((m) => m.output);\n}\n\n/**\n * Executes a single group member (single-step or subgraph).\n */\nexport async function executeGroupMember(\n memberRuntime: GroupMemberRuntime,\n parentInput: unknown,\n ctx: StepContext,\n parentStepOutputs?: ReadonlyMap<string, unknown>,\n onStateChange?: () => void,\n): Promise<void> {\n memberRuntime.status = \"running\";\n memberRuntime.startedAt = Date.now();\n onStateChange?.();\n\n try {\n if (isSubgraphMember(memberRuntime.member)) {\n const subgraph = memberRuntime.member;\n\n // Wait for and resolve external dependencies from parent step outputs\n let injectedSteps: Map<string, unknown> | undefined;\n if (subgraph.externalDeps && parentStepOutputs) {\n const deps = Object.entries(subgraph.externalDeps);\n // Wait until all external dep parent steps have outputs\n while (\n !ctx.signal.aborted &&\n deps.some(([, parentName]) => !parentStepOutputs.has(parentName))\n ) {\n await new Promise((r) => setTimeout(r, 10));\n }\n injectedSteps = new Map();\n for (const [childStepName, parentStepName] of deps) {\n injectedSteps.set(\n childStepName,\n parentStepOutputs.get(parentStepName),\n );\n }\n }\n\n // Subgraph member: create a child FlowRun with injected external deps\n // Hook into child events to bubble state changes to parent\n const childHooks = onStateChange\n ? {\n onStepComplete: onStateChange,\n onStepError: onStateChange,\n onStepStart: onStateChange,\n }\n : undefined;\n const childRun = subgraph.flow.run({\n hooks: childHooks,\n injectedSteps,\n });\n memberRuntime.childRun = childRun;\n\n // Abort child if parent aborts\n const onAbort = (): void => childRun.abort();\n ctx.signal.addEventListener(\"abort\", onAbort);\n\n const result = await childRun.result;\n\n ctx.signal.removeEventListener(\"abort\", onAbort);\n\n if (result.status === \"error\") {\n // Find the first error step for the error message\n const errorStep = result.steps.find((s) => s.status === \"error\");\n throw new Error(errorStep?.error ?? \"Subgraph failed\");\n }\n\n // Output is the terminal step's output, or the last step's output\n const terminalStep = result.steps.find(\n (s) =>\n s.status === \"success\" &&\n subgraph.flow.steps.some(\n (d: { name: string; terminal: boolean }) =>\n d.name === s.name && d.terminal,\n ),\n );\n memberRuntime.output =\n terminalStep?.output ??\n result.steps.findLast((s) => s.status === \"success\")?.output;\n } else {\n const single = memberRuntime.member as SingleMember<unknown, unknown>;\n memberRuntime.output = await invokeHandler(\n single.execute,\n parentInput,\n ctx,\n );\n }\n memberRuntime.status = \"success\";\n memberRuntime.completedAt = Date.now();\n onStateChange?.();\n } catch (error) {\n memberRuntime.status = \"error\";\n memberRuntime.completedAt = Date.now();\n onStateChange?.();\n memberRuntime.error =\n error instanceof Error ? error.message : String(error);\n throw error;\n }\n}\n","export class History {\n private readonly store = new Map<string, unknown>();\n\n set(key: string, value: unknown): void {\n this.store.set(key, value);\n }\n\n get<T>(key: string): T | undefined {\n return this.store.get(key) as T | undefined;\n }\n\n has(key: string): boolean {\n return this.store.has(key);\n }\n\n snapshot(): ReadonlyMap<string, unknown> {\n return new Map(this.store);\n }\n}\n","import type { Flow } from \"./flow.js\";\nimport { type FlowSnapshot, createSnapshot } from \"./snapshot.js\";\nimport {\n getReadySteps,\n getReadyWithFailures,\n getSkippableSteps,\n} from \"./graph.js\";\nimport {\n type GroupRuntime,\n addGroupMembers,\n collectGroupOutputs,\n collectSuccessOutputs,\n createGroupRuntime,\n executeGroupMember,\n isGroupComplete,\n} from \"./group.js\";\nimport { History } from \"./history.js\";\nimport type {\n FlowHooks,\n FlowRunResult,\n GroupMember,\n RunHandle,\n RunOptions,\n RunStatus,\n StepContext,\n StepDefinition,\n StepHandler,\n StepRecord,\n StepResult,\n StepStatus,\n} from \"./types.js\";\nimport { invokeHandler } from \"./types.js\";\n\nconst generateRunId = (): string => crypto.randomUUID().slice(0, 8);\n\n/**\n * Runtime execution engine for a single flow run.\n * Uses wave-based scheduling: collect ready steps, launch concurrently,\n * await all, find newly ready steps, repeat.\n */\nexport class FlowRun<\n TRegistry extends Record<string, unknown> = Record<string, unknown>,\n> {\n readonly runId: string;\n private readonly flow: Flow<TRegistry>;\n private readonly hooks: FlowHooks;\n private readonly failFast: boolean;\n private readonly abortController: AbortController;\n\n private readonly history: History;\n private readonly stepDefs: Map<string, StepDefinition>;\n private readonly stepRecords: Map<string, StepRecord>;\n private readonly stepOutputs: Map<string, unknown>;\n\n private readonly groupRuntimes: Map<string, GroupRuntime>;\n private readonly providedSlots: Map<string, StepHandler<unknown, unknown>>;\n private readonly providedData: Map<string, unknown>;\n\n private status: RunStatus = \"idle\";\n private startedAt = 0;\n\n private resolveResult!: (result: FlowRunResult) => void;\n readonly result: Promise<FlowRunResult>;\n\n private loopRunning = false;\n private readonly pendingGroupStarts: GroupRuntime[] = [];\n private dynamicStepsAdded = false;\n\n constructor(flow: Flow<TRegistry>, options?: RunOptions) {\n this.runId = generateRunId();\n this.flow = flow;\n this.hooks = options?.hooks ?? {};\n this.failFast = options?.failFast ?? false;\n this.abortController = new AbortController();\n this.history = new History();\n\n this.stepDefs = new Map();\n this.stepRecords = new Map();\n this.stepOutputs = new Map();\n this.groupRuntimes = new Map();\n this.providedSlots = new Map();\n this.providedData = new Map();\n\n // Initialize step definitions from the flow\n for (const step of flow.steps) {\n this.stepDefs.set(step.name, step);\n this.stepRecords.set(step.name, {\n name: step.name,\n parentNames: step.parentNames,\n status: \"pending\",\n });\n }\n\n // Initialize group runtimes\n for (const group of flow.groups) {\n this.groupRuntimes.set(\n group.name,\n createGroupRuntime(group.name, group.dependsOn),\n );\n }\n\n // Inject pre-resolved steps (for cross-boundary subgraph deps)\n if (options?.injectedSteps) {\n for (const [name, output] of options.injectedSteps) {\n if (!this.stepDefs.has(name)) {\n // Create a synthetic step definition\n this.stepDefs.set(name, {\n allowFailures: false,\n handler: async () => output,\n name,\n parentNames: [],\n terminal: false,\n });\n }\n this.stepRecords.set(name, {\n completedAt: Date.now(),\n durationMs: 0,\n name,\n output,\n parentNames: [],\n startedAt: Date.now(),\n status: \"success\",\n });\n this.stepOutputs.set(name, output);\n }\n }\n\n this.result = new Promise((resolve) => {\n this.resolveResult = resolve;\n });\n\n // Start execution immediately\n this.startExecution();\n }\n\n /**\n * Read-only snapshot of current step records.\n */\n get steps(): readonly StepRecord[] {\n return Array.from(this.stepRecords.values());\n }\n\n /**\n * JSON-serializable snapshot of the current flow + run state.\n */\n snapshot(): FlowSnapshot {\n return createSnapshot({\n flow: this.flow,\n groupRuntimes: this.groupRuntimes,\n run: {\n completedAt: undefined,\n runId: this.runId,\n startedAt: this.startedAt,\n status: this.status,\n },\n stepRecords: this.stepRecords,\n });\n }\n\n /**\n * Abort the run — signals all in-progress steps.\n */\n abort(): void {\n this.abortController.abort();\n }\n\n /**\n * Add a step dynamically during execution.\n */\n addStep(def: StepDefinition): void {\n this.stepDefs.set(def.name, def);\n const record: StepRecord = {\n name: def.name,\n parentNames: def.parentNames,\n status: \"pending\",\n };\n this.stepRecords.set(def.name, record);\n this.fireHook(\"onStepAdded\", record);\n this.dynamicStepsAdded = true;\n\n // If the loop is idle, restart it\n if (!this.loopRunning && this.status === \"running\") {\n this.executionLoop();\n }\n }\n\n /**\n * Spawn members into a group and auto-seal it.\n */\n spawnGroup(groupName: string, members: readonly GroupMember[]): void {\n const grp = this.groupRuntimes.get(groupName);\n if (!grp) {\n throw new Error(`Unknown group \"${groupName}\"`);\n }\n addGroupMembers(grp, members, true);\n this.startOrDeferGroup(grp);\n }\n\n /**\n * Add a single member to a group (without sealing).\n */\n addGroupMember(groupName: string, member: GroupMember): void {\n const grp = this.groupRuntimes.get(groupName);\n if (!grp) {\n throw new Error(`Unknown group \"${groupName}\"`);\n }\n addGroupMembers(grp, [member], false);\n this.startOrDeferGroup(grp);\n }\n\n /**\n * Seal a group — no more members can be added.\n */\n sealGroup(groupName: string): void {\n const group = this.groupRuntimes.get(groupName);\n if (!group) {\n throw new Error(`Unknown group \"${groupName}\"`);\n }\n group.sealed = true;\n this.checkGroupCompletion(group);\n }\n\n /**\n * Provide a step implementation (slot fill) or external data.\n */\n provide(\n path: string,\n value: StepHandler<unknown, unknown> | Record<string, unknown> | unknown,\n ): void {\n if (typeof value === \"function\" || isExecutableValue(value)) {\n this.providedSlots.set(path, value as StepHandler<unknown, unknown>);\n } else {\n this.providedData.set(path, value);\n }\n }\n\n // --- Private helpers ---\n\n private createContext(): StepContext {\n const runHandle: RunHandle = {\n addGroupMember: (groupName, member) =>\n this.addGroupMember(groupName, member),\n provide: (path, value) => this.provide(path, value),\n sealGroup: (groupName) => this.sealGroup(groupName),\n spawnGroup: (groupName, members) => this.spawnGroup(groupName, members),\n };\n\n return {\n history: this.history,\n provided<T>(): T {\n return undefined as T;\n },\n run: runHandle,\n runId: this.runId,\n signal: this.abortController.signal,\n };\n }\n\n // --- Private execution logic ---\n\n private async startExecution(): Promise<void> {\n this.status = \"running\";\n this.startedAt = Date.now();\n await this.executionLoop();\n }\n\n private async executionLoop(): Promise<void> {\n if (this.loopRunning) return;\n this.loopRunning = true;\n\n try {\n while (!this.abortController.signal.aborted) {\n this.dynamicStepsAdded = false;\n\n // Mark skippable steps\n this.markSkippableSteps();\n\n // Collect ready steps (normal + allowFailures)\n const allDefs = Array.from(this.stepDefs.values());\n const statuses = this.getStatusMap();\n const readyNormal = getReadySteps(allDefs, statuses);\n const readyWithFailures = getReadyWithFailures(allDefs, statuses);\n const ready = [...new Set([...readyNormal, ...readyWithFailures])];\n\n if (ready.length === 0) {\n // Check if there are still running steps (from groups etc.)\n const hasRunning = Array.from(this.stepRecords.values()).some(\n (r) => r.status === \"running\",\n );\n const hasPendingGroups = Array.from(this.groupRuntimes.values()).some(\n (g) => !isGroupComplete(g) && g.members.length > 0,\n );\n\n if (!hasRunning && !hasPendingGroups && !this.dynamicStepsAdded) {\n break;\n }\n\n // Wait a tick for dynamic steps or group completions\n if (!this.dynamicStepsAdded) {\n await new Promise((resolve) => setTimeout(resolve, 1));\n continue;\n }\n continue;\n }\n\n // Launch ready steps concurrently — each completion re-triggers the loop\n // so dependent steps start immediately, not after the whole wave settles\n await new Promise<void>((resolveWave) => {\n let pending = ready.length;\n for (const name of ready) {\n this.executeStep(name).finally(() => {\n pending--;\n\n if (this.failFast && this.hasAnyError()) {\n this.abortController.abort();\n }\n\n // Re-check for newly ready steps after each completion\n this.scheduleReadySteps();\n\n if (pending === 0) resolveWave();\n });\n }\n });\n }\n } finally {\n this.loopRunning = false;\n }\n\n this.completeRun();\n }\n\n /**\n * Check for and launch any newly ready steps without waiting for the full wave.\n * Called after each individual step completion.\n */\n private scheduleReadySteps(): void {\n this.markSkippableSteps();\n this.flushPendingGroups();\n\n const allDefs = Array.from(this.stepDefs.values());\n const statuses = this.getStatusMap();\n const readyNormal = getReadySteps(allDefs, statuses);\n const readyWithFailures = getReadyWithFailures(allDefs, statuses);\n const ready = [...new Set([...readyNormal, ...readyWithFailures])];\n\n for (const name of ready) {\n this.executeStep(name).finally(() => {\n this.scheduleReadySteps();\n });\n }\n }\n\n private async executeStep(name: string): Promise<void> {\n const def = this.stepDefs.get(name)!;\n const record = this.stepRecords.get(name)!;\n\n // Mark as running\n (record as { status: StepStatus }).status = \"running\";\n (record as { startedAt: number }).startedAt = Date.now();\n this.fireHook(\"onStepStart\", record);\n\n try {\n // Build input from parent outputs\n const input = this.buildInput(def);\n\n const ctx = this.createContext();\n\n const output = await invokeHandler(def.handler, input, ctx);\n\n (record as { status: StepStatus }).status = \"success\";\n (record as { completedAt: number }).completedAt = Date.now();\n (record as { durationMs: number }).durationMs =\n record.completedAt! - record.startedAt!;\n (record as { output: unknown }).output = output;\n this.stepOutputs.set(name, output);\n\n this.fireHook(\"onStepComplete\", record);\n this.flushPendingGroups();\n } catch (error) {\n (record as { status: StepStatus }).status = \"error\";\n (record as { completedAt: number }).completedAt = Date.now();\n (record as { durationMs: number }).durationMs =\n record.completedAt! - record.startedAt!;\n (record as { error: string }).error =\n error instanceof Error ? error.message : String(error);\n\n this.fireHook(\"onStepError\", record);\n }\n }\n\n private buildInput(def: StepDefinition): unknown {\n const input: Record<string, unknown> = {};\n\n for (const parentName of def.parentNames) {\n // Check if it's a group\n const groupRuntime = this.groupRuntimes.get(parentName);\n if (groupRuntime) {\n input[parentName] = def.allowFailures\n ? collectGroupOutputs(groupRuntime)\n : collectSuccessOutputs(groupRuntime);\n continue;\n }\n\n // Regular step parent\n if (def.allowFailures) {\n const parentRecord = this.stepRecords.get(parentName);\n if (parentRecord?.status === \"success\") {\n input[parentName] = {\n status: \"success\",\n value: this.stepOutputs.get(parentName),\n } satisfies StepResult<unknown>;\n } else if (parentRecord?.status === \"error\") {\n input[parentName] = {\n error: parentRecord.error ?? \"Unknown error\",\n status: \"error\",\n } satisfies StepResult<unknown>;\n } else {\n input[parentName] = {\n status: \"skipped\",\n } satisfies StepResult<unknown>;\n }\n } else {\n input[parentName] = this.stepOutputs.get(parentName);\n }\n }\n\n if (def.transform) {\n return def.transform(input);\n }\n\n return input;\n }\n\n private markSkippableSteps(): void {\n const allDefs = Array.from(this.stepDefs.values());\n const statuses = this.getStatusMap();\n let changed = true;\n\n while (changed) {\n changed = false;\n const skippable = getSkippableSteps(allDefs, statuses);\n for (const name of skippable) {\n const record = this.stepRecords.get(name)!;\n (record as { status: StepStatus }).status = \"skipped\";\n statuses.set(name, \"skipped\");\n changed = true;\n }\n }\n }\n\n private getStatusMap(): Map<string, StepStatus> {\n const map = new Map<string, StepStatus>();\n for (const [name, record] of this.stepRecords) {\n map.set(name, record.status);\n }\n // Groups appear as step-like nodes\n for (const [name, group] of this.groupRuntimes) {\n if (isGroupComplete(group)) {\n const allSuccess = group.members.every((m) => m.status === \"success\");\n map.set(name, allSuccess ? \"success\" : \"error\");\n } else if (group.members.some((m) => m.status === \"running\")) {\n map.set(name, \"running\");\n } else if (group.members.length > 0) {\n map.set(name, \"running\");\n } else {\n map.set(name, \"pending\");\n }\n }\n return map;\n }\n\n private hasAnyError(): boolean {\n for (const record of this.stepRecords.values()) {\n if (record.status === \"error\") return true;\n }\n return false;\n }\n\n private areGroupDependenciesMet(group: GroupRuntime): boolean {\n for (const dep of group.dependsOn) {\n const record = this.stepRecords.get(dep);\n if (!record || record.status !== \"success\") return false;\n }\n return true;\n }\n\n private startOrDeferGroup(grp: GroupRuntime): void {\n if (this.areGroupDependenciesMet(grp)) {\n this.startGroupMembers(grp);\n } else {\n // Defer — will be flushed after the currently-executing step completes\n if (!this.pendingGroupStarts.includes(grp)) {\n this.pendingGroupStarts.push(grp);\n }\n }\n }\n\n private flushPendingGroups(): void {\n const toFlush = [...this.pendingGroupStarts];\n this.pendingGroupStarts.length = 0;\n for (const grp of toFlush) {\n if (this.areGroupDependenciesMet(grp)) {\n this.startGroupMembers(grp);\n } else {\n // Still not ready — re-defer\n this.pendingGroupStarts.push(grp);\n }\n }\n }\n\n private startGroupMembers(group: GroupRuntime): void {\n if (!this.areGroupDependenciesMet(group)) return;\n\n // Build parent input from group dependencies\n const parentInput: Record<string, unknown> = {};\n for (const dep of group.dependsOn) {\n parentInput[dep] = this.stepOutputs.get(dep);\n }\n\n const ctx = this.createContext();\n\n for (const member of group.members) {\n if (member.status !== \"pending\") continue;\n\n executeGroupMember(member, parentInput, ctx, this.stepOutputs, () =>\n this.fireHook(\"onChange\", undefined),\n )\n .then(() => {\n this.checkGroupCompletion(group);\n })\n .catch(() => {\n this.checkGroupCompletion(group);\n });\n }\n }\n\n private checkGroupCompletion(group: GroupRuntime): void {\n if (isGroupComplete(group)) {\n // Signal dynamic step addition to wake the loop\n this.dynamicStepsAdded = true;\n this.fireHook(\"onChange\", undefined);\n }\n }\n\n private completeRun(): void {\n // Determine final status\n const terminalSteps = Array.from(this.stepDefs.values()).filter(\n (d) => d.terminal,\n );\n const stepsToCheck =\n terminalSteps.length > 0\n ? terminalSteps.map((d) => this.stepRecords.get(d.name)!)\n : Array.from(this.stepRecords.values());\n\n const hasError = stepsToCheck.some((r) => r.status === \"error\");\n this.status = hasError ? \"error\" : \"success\";\n\n const result: FlowRunResult = {\n completedAt: Date.now(),\n history: this.history.snapshot(),\n runId: this.runId,\n startedAt: this.startedAt,\n status: this.status,\n steps: Array.from(this.stepRecords.values()),\n };\n\n this.fireHook(\"onRunComplete\", result);\n this.resolveResult(result);\n }\n\n private fireHook(\n hookName: keyof FlowHooks,\n arg?: StepRecord | FlowRunResult | undefined,\n ): void {\n try {\n const hook = this.hooks[hookName];\n if (hook) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (hook as (...args: any[]) => void)(arg);\n }\n // Also fire onChange for any event\n if (hookName !== \"onChange\" && this.hooks.onChange) {\n this.hooks.onChange();\n }\n } catch {\n // Hooks should not break execution\n }\n }\n}\n\nfunction isExecutableValue(value: unknown): boolean {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"execute\" in value &&\n typeof (value as Record<string, unknown>).execute === \"function\"\n );\n}\n","import { validateAcyclic } from \"./graph.js\";\nimport { FlowRun } from \"./flow-run.js\";\nimport type { GroupDefinition, RunOptions, StepDefinition } from \"./types.js\";\n\n/**\n * Immutable DAG blueprint produced by FlowBuilder.build().\n * Call .run() to create execution instances.\n */\nexport class Flow<\n TRegistry extends Record<string, unknown> = Record<string, unknown>,\n> {\n readonly name: string;\n readonly steps: readonly StepDefinition[];\n readonly groups: readonly GroupDefinition[];\n\n constructor(\n name: string,\n steps: StepDefinition[],\n groups: GroupDefinition[],\n ) {\n // Validate the DAG at build time — include groups as graph nodes\n const groupNodes = groups.map((g) => ({\n name: g.name,\n parentNames: g.dependsOn,\n }));\n validateAcyclic([...steps, ...groupNodes]);\n\n this.name = name;\n this.steps = Object.freeze([...steps]);\n this.groups = Object.freeze([...groups]);\n }\n\n /**\n * Creates a new FlowRun instance.\n * Multiple runs can execute concurrently from the same Flow.\n */\n run(options?: RunOptions): FlowRun<TRegistry> {\n return new FlowRun<TRegistry>(this, options);\n }\n}\n","import { DuplicateStepError, UnknownParentError } from \"./errors.js\";\nimport { Flow } from \"./flow.js\";\nimport type {\n GroupDefinition,\n GroupRef,\n InputMapper,\n StepDefinition,\n StepHandler,\n StepOptions,\n} from \"./types.js\";\nimport { isGroupRef } from \"./types.js\";\n\n/**\n * Chainable builder for constructing type-safe flow graphs.\n *\n * Each `.step()` call returns a new FlowBuilder with an expanded registry.\n * Positional arguments allow TypeScript to infer literal string types\n * without needing `as const`.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport class FlowBuilder<TRegistry extends Record<string, unknown> = {}> {\n private readonly flowName: string;\n private readonly steps: StepDefinition[];\n private readonly groups: GroupDefinition[];\n private readonly knownNames: Set<string>;\n\n constructor(\n flowName: string,\n steps: StepDefinition[] = [],\n groups: GroupDefinition[] = [],\n knownNames?: Set<string>,\n ) {\n this.flowName = flowName;\n this.steps = steps;\n this.groups = groups;\n this.knownNames = knownNames ?? new Set(steps.map((s) => s.name));\n }\n\n /**\n * Root step — no parents.\n * .step(\"name\", executeFn)\n * .step(\"name\", executableInstance)\n */\n step<TName extends string, TOutput>(\n name: TName,\n handler: StepHandler<Record<string, unknown>, TOutput>,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with parents — input auto-derived from parent outputs.\n * .step(\"name\", [\"parent1\", \"parent2\"], executeFn)\n */\n step<\n TName extends string,\n TParents extends readonly (keyof TRegistry & string)[],\n TOutput,\n >(\n name: TName,\n parents: [...TParents],\n handler: StepHandler<{ [K in TParents[number]]: TRegistry[K] }, TOutput>,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with parents + options object.\n * .step(\"name\", [\"parent1\"], { execute, transform?, allowFailures?, terminal? })\n */\n step<\n TName extends string,\n TParents extends readonly (keyof TRegistry & string)[],\n TOutput,\n >(\n name: TName,\n parents: [...TParents],\n options: StepOptions<{ [K in TParents[number]]: TRegistry[K] }, TOutput>,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with group ref dependencies.\n * .step(\"name\", [group(\"reviews\")], executeFn)\n */\n step<TName extends string, TDeps extends readonly unknown[], TOutput>(\n name: TName,\n deps: [...TDeps],\n handler:\n | StepHandler<\n {\n [K in TDeps[number] as K extends string\n ? K\n : K extends GroupRef<infer G>\n ? G\n : never]: K extends string\n ? TRegistry[K & keyof TRegistry]\n : K extends GroupRef<infer G>\n ? TRegistry[G & keyof TRegistry]\n : never;\n },\n TOutput\n >\n | StepOptions<\n {\n [K in TDeps[number] as K extends string\n ? K\n : K extends GroupRef<infer G>\n ? G\n : never]: K extends string\n ? TRegistry[K & keyof TRegistry]\n : K extends GroupRef<infer G>\n ? TRegistry[G & keyof TRegistry]\n : never;\n },\n TOutput\n >,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with parents + typed input mapper + handler.\n * .step(\"name\", [\"parent1\"], mapper, executeFn)\n */\n step<\n TName extends string,\n TParents extends readonly (keyof TRegistry & string)[],\n TMapped,\n TOutput,\n >(\n name: TName,\n parents: [...TParents],\n inputMapper: InputMapper<\n { [K in TParents[number]]: TRegistry[K] },\n TMapped\n >,\n handler: StepHandler<TMapped, TOutput>,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with parents + typed input mapper + options.\n * .step(\"name\", [\"parent1\"], mapper, { execute, terminal?, allowFailures? })\n */\n step<\n TName extends string,\n TParents extends readonly (keyof TRegistry & string)[],\n TMapped,\n TOutput,\n >(\n name: TName,\n parents: [...TParents],\n inputMapper: InputMapper<\n { [K in TParents[number]]: TRegistry[K] },\n TMapped\n >,\n options: Omit<StepOptions<TMapped, TOutput>, \"transform\">,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with group ref dependencies + typed input mapper + handler.\n * .step(\"name\", [group(\"reviews\")], mapper, executeFn)\n */\n step<\n TName extends string,\n TDeps extends readonly unknown[],\n TMapped,\n TOutput,\n >(\n name: TName,\n deps: [...TDeps],\n inputMapper: InputMapper<\n {\n [K in TDeps[number] as K extends string\n ? K\n : K extends GroupRef<infer G>\n ? G\n : never]: K extends string\n ? TRegistry[K & keyof TRegistry]\n : K extends GroupRef<infer G>\n ? TRegistry[G & keyof TRegistry]\n : never;\n },\n TMapped\n >,\n handler: StepHandler<TMapped, TOutput>,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n /**\n * Step with group ref dependencies + typed input mapper + options.\n * .step(\"name\", [group(\"reviews\")], mapper, { execute, terminal?, allowFailures? })\n */\n step<\n TName extends string,\n TDeps extends readonly unknown[],\n TMapped,\n TOutput,\n >(\n name: TName,\n deps: [...TDeps],\n inputMapper: InputMapper<\n {\n [K in TDeps[number] as K extends string\n ? K\n : K extends GroupRef<infer G>\n ? G\n : never]: K extends string\n ? TRegistry[K & keyof TRegistry]\n : K extends GroupRef<infer G>\n ? TRegistry[G & keyof TRegistry]\n : never;\n },\n TMapped\n >,\n options: Omit<StepOptions<TMapped, TOutput>, \"transform\">,\n ): FlowBuilder<TRegistry & Record<TName, TOutput>>;\n\n // Implementation\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n step(\n name: string,\n parentsOrHandler: any,\n handlerOrOptions?: any,\n stepDef?: any,\n ): any {\n if (this.knownNames.has(name)) {\n throw new DuplicateStepError(name);\n }\n\n let parentNames: string[] = [];\n let handler: StepHandler<unknown, unknown>;\n let allowFailures = false;\n let terminal = false;\n let transform: ((input: unknown) => unknown) | undefined;\n\n if (Array.isArray(parentsOrHandler)) {\n // .step(name, parents, ...)\n parentNames = parentsOrHandler.map((p: unknown) => {\n if (isGroupRef(p)) return p.groupName;\n return p as string;\n });\n\n if (stepDef !== undefined) {\n // 4-arg: .step(name, parents, inputMapper, handler/options)\n transform = handlerOrOptions as (input: unknown) => unknown;\n if (\n typeof stepDef === \"object\" &&\n stepDef !== null &&\n \"execute\" in stepDef\n ) {\n const opts = stepDef as StepOptions<unknown, unknown>;\n handler = opts.execute;\n allowFailures = opts.allowFailures ?? false;\n terminal = opts.terminal ?? false;\n } else {\n handler = stepDef as StepHandler<unknown, unknown>;\n }\n } else if (\n typeof handlerOrOptions === \"object\" &&\n handlerOrOptions !== null &&\n \"execute\" in handlerOrOptions\n ) {\n const opts = handlerOrOptions as StepOptions<unknown, unknown>;\n handler = opts.execute;\n allowFailures = opts.allowFailures ?? false;\n terminal = opts.terminal ?? false;\n transform = opts.transform as ((input: unknown) => unknown) | undefined;\n } else {\n handler = handlerOrOptions as StepHandler<unknown, unknown>;\n }\n } else {\n // .step(name, handler) — root step\n handler = parentsOrHandler as StepHandler<unknown, unknown>;\n }\n\n // Validate parents exist\n for (const parent of parentNames) {\n if (!this.knownNames.has(parent)) {\n throw new UnknownParentError(name, parent);\n }\n }\n\n const newSteps = [\n ...this.steps,\n {\n allowFailures,\n handler,\n name,\n parentNames,\n terminal,\n transform,\n } satisfies StepDefinition,\n ];\n const newKnown = new Set(this.knownNames);\n newKnown.add(name);\n\n return new FlowBuilder(this.flowName, newSteps, [...this.groups], newKnown);\n }\n\n /**\n * Declare a typed group for dynamic fan-in.\n * .group<TOut>(\"reviews\", { dependsOn: [\"arbiter\"] })\n */\n group<TOut, TName extends string = string>(\n name: TName,\n options: { dependsOn?: (keyof TRegistry & string)[] } = {},\n ): FlowBuilder<TRegistry & Record<TName, TOut[]>> {\n if (this.knownNames.has(name)) {\n throw new DuplicateStepError(name);\n }\n\n const dependsOn = options.dependsOn ?? [];\n for (const dep of dependsOn) {\n if (!this.knownNames.has(dep)) {\n throw new UnknownParentError(name, dep);\n }\n }\n\n const newGroups = [...this.groups, { dependsOn, name }];\n const newKnown = new Set(this.knownNames);\n newKnown.add(name);\n\n return new FlowBuilder(\n this.flowName,\n [...this.steps],\n newGroups,\n newKnown,\n ) as FlowBuilder<TRegistry & Record<typeof name, TOut[]>>;\n }\n\n /**\n * Validates the DAG and returns an immutable Flow.\n */\n build(): Flow<TRegistry> {\n return new Flow<TRegistry>(this.flowName, this.steps, this.groups);\n }\n}\n\n/**\n * Entry point: creates a new FlowBuilder.\n */\nexport function flow(name: string): FlowBuilder {\n return new FlowBuilder(name);\n}\n","import { flow as flowBuilder } from \"./flow-builder.js\";\nimport type { StepHandler, SubgraphMember } from \"./types.js\";\n\nexport interface PipelineStepDef {\n execute?: StepHandler<unknown, unknown>;\n name: string;\n}\n\n/**\n * Convenience builder that creates a SubgraphMember with a linear DAG.\n * Each step depends on the previous one, forming a sequential pipeline.\n *\n * ```typescript\n * pipeline(\"tone-analysis\", [\n * { name: \"detect\", execute: detectFn },\n * { name: \"classify\", execute: classifyFn },\n * { name: \"score\", execute: scoreFn },\n * ])\n * ```\n *\n * is equivalent to building a flow:\n * detect → classify → score (terminal)\n */\nexport function pipeline(\n name: string,\n steps: PipelineStepDef[],\n): SubgraphMember {\n if (steps.length === 0) {\n throw new Error(`Pipeline \"${name}\" must have at least one step`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let builder: any = flowBuilder(`${name}`);\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n const handler = step.execute ?? (async (input: unknown) => input);\n const isLast = i === steps.length - 1;\n\n if (i === 0) {\n // Root step — no parents\n builder = isLast\n ? builder.step(step.name, {\n execute: handler,\n terminal: true,\n })\n : builder.step(step.name, handler);\n } else {\n // Chain: depends on previous step\n const parents = [steps[i - 1]!.name];\n builder = isLast\n ? builder.step(step.name, parents, {\n execute: handler,\n terminal: true,\n })\n : builder.step(step.name, parents, handler);\n }\n }\n\n return { flow: builder.build(), name };\n}\n"],"mappings":"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","names":["group","flow","group"]}
|
package/dist/react/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magic-marker/nurt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A type-safe, zero-dependency DAG execution engine for TypeScript",
|
|
6
6
|
"exports": {
|
|
@@ -17,18 +17,6 @@
|
|
|
17
17
|
"dist",
|
|
18
18
|
"README.md"
|
|
19
19
|
],
|
|
20
|
-
"scripts": {
|
|
21
|
-
"build": "tsx scripts/build.ts",
|
|
22
|
-
"dev": "tsx scripts/build.ts --watch",
|
|
23
|
-
"lint": "eslint .",
|
|
24
|
-
"lint:fix": "eslint . --fix",
|
|
25
|
-
"typecheck": "tsc --noEmit",
|
|
26
|
-
"test": "vitest run",
|
|
27
|
-
"test:watch": "vitest",
|
|
28
|
-
"prepublishOnly": "pnpm build",
|
|
29
|
-
"storybook": "storybook dev -p 6006 --no-open",
|
|
30
|
-
"build-storybook": "storybook build -o storybook-static"
|
|
31
|
-
},
|
|
32
20
|
"peerDependencies": {
|
|
33
21
|
"elkjs": ">=0.9.0",
|
|
34
22
|
"react": "^18.0.0 || ^19.0.0"
|
|
@@ -62,5 +50,16 @@
|
|
|
62
50
|
"tsx": "^4.21.0",
|
|
63
51
|
"typescript": "^5.9.3",
|
|
64
52
|
"vitest": "^4.0.16"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsx scripts/build.ts",
|
|
56
|
+
"dev": "tsx scripts/build.ts --watch",
|
|
57
|
+
"lint": "eslint .",
|
|
58
|
+
"lint:fix": "eslint . --fix",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"test": "vitest run",
|
|
61
|
+
"test:watch": "vitest",
|
|
62
|
+
"storybook": "storybook dev -p 6006 --no-open",
|
|
63
|
+
"build-storybook": "storybook build -o storybook-static"
|
|
65
64
|
}
|
|
66
|
-
}
|
|
65
|
+
}
|