@magic-marker/nurt 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +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"]}
@@ -0,0 +1,123 @@
1
+ import { i as FlowSnapshot, l as FlowSnapshotStep, e as StepStatus } from '../flow-DqIejS_0.js';
2
+ import React from 'react';
3
+
4
+ interface NurtFlowChartProps {
5
+ className?: string;
6
+ onNodeClick?: (nodeName: string) => void;
7
+ snapshot: FlowSnapshot;
8
+ }
9
+ declare const NurtFlowChart: React.FC<NurtFlowChartProps>;
10
+
11
+ interface NurtFlowChartWithPanelProps {
12
+ className?: string;
13
+ snapshot: FlowSnapshot;
14
+ }
15
+ declare const NurtFlowChartWithPanel: React.FC<NurtFlowChartWithPanelProps>;
16
+
17
+ interface NurtStepDetailPanelProps {
18
+ onClose: () => void;
19
+ onNavigate?: (nodeName: string) => void;
20
+ selectedNode: string;
21
+ snapshot: FlowSnapshot;
22
+ }
23
+ declare const NurtStepDetailPanel: React.FC<NurtStepDetailPanelProps>;
24
+
25
+ interface LayoutNode {
26
+ groupName?: string;
27
+ height: number;
28
+ id: string;
29
+ label: string;
30
+ members?: LayoutMemberNode[];
31
+ status: string;
32
+ step?: FlowSnapshotStep;
33
+ type: "step" | "group";
34
+ width: number;
35
+ x: number;
36
+ y: number;
37
+ }
38
+ interface LayoutMemberNode {
39
+ durationMs?: number;
40
+ error?: string;
41
+ height: number;
42
+ name: string;
43
+ status: string;
44
+ subgraphEdges?: LayoutSubgraphEdge[];
45
+ subgraphSteps?: LayoutSubgraphStep[];
46
+ type: "single" | "subgraph";
47
+ width: number;
48
+ x: number;
49
+ y: number;
50
+ }
51
+ interface LayoutSubgraphStep {
52
+ durationMs?: number;
53
+ height: number;
54
+ name: string;
55
+ status: string;
56
+ width: number;
57
+ x: number;
58
+ y: number;
59
+ }
60
+ interface LayoutSubgraphEdge {
61
+ bendPoints?: Array<{
62
+ x: number;
63
+ y: number;
64
+ }>;
65
+ memberName: string;
66
+ x1: number;
67
+ x2: number;
68
+ y1: number;
69
+ y2: number;
70
+ }
71
+ interface LayoutEdge {
72
+ bendPoints?: Array<{
73
+ x: number;
74
+ y: number;
75
+ }>;
76
+ source: string;
77
+ target: string;
78
+ x1: number;
79
+ x2: number;
80
+ y1: number;
81
+ y2: number;
82
+ }
83
+ interface ExternalRefEdge {
84
+ sourceStepName: string;
85
+ targetMemberName: string;
86
+ x1: number;
87
+ x2: number;
88
+ y1: number;
89
+ y2: number;
90
+ }
91
+ interface LayoutResult {
92
+ edges: LayoutEdge[];
93
+ externalRefEdges: ExternalRefEdge[];
94
+ height: number;
95
+ nodes: LayoutNode[];
96
+ width: number;
97
+ }
98
+ /**
99
+ * Computes a layered DAG layout using ELK.
100
+ * Groups are compound nodes with member children.
101
+ * Returns absolute coordinates for all elements.
102
+ */
103
+ declare function layoutSnapshot(snapshot: FlowSnapshot): Promise<LayoutResult>;
104
+
105
+ declare const FlowEdge: React.FC<{
106
+ edge: LayoutEdge;
107
+ }>;
108
+
109
+ declare const formatDuration: (ms: number) => string;
110
+ declare const statusIndicator: (status: StepStatus | string) => string;
111
+ declare const getNodeStyle: (status: string, hovered: boolean) => {
112
+ fill: string;
113
+ opacity: number;
114
+ stroke: string;
115
+ strokeWidth: number;
116
+ };
117
+ declare const getMemberStyle: (status: string) => {
118
+ fill: string;
119
+ stroke: string;
120
+ };
121
+ declare const statusTextColor: (status: string) => string;
122
+
123
+ export { type ExternalRefEdge, FlowEdge, type LayoutEdge, type LayoutMemberNode, type LayoutNode, type LayoutResult, type LayoutSubgraphEdge, type LayoutSubgraphStep, NurtFlowChart, type NurtFlowChartProps, NurtFlowChartWithPanel, type NurtFlowChartWithPanelProps, NurtStepDetailPanel, type NurtStepDetailPanelProps, formatDuration, getMemberStyle, getNodeStyle, layoutSnapshot, statusIndicator, statusTextColor };