{"version":3,"file":"engine-DUzM-gJM.mjs","names":["toError"],"sources":["../src/core/async-iterator.ts","../src/core/engine.ts"],"sourcesContent":["export interface AbortableSubscriber<T> {\n  push(value: T, signal: AbortSignal): Promise<void>\n  close(): void\n}\n\nexport interface AsyncDisposableIterator<T> extends AsyncIterableIterator<T> {\n  [Symbol.asyncDispose](): Promise<void>\n}\n\ninterface PendingPush<T> {\n  value: T\n  resolve: () => void\n  reject: (error: Error) => void\n  signal: AbortSignal\n  onAbort: () => void\n  settled: boolean\n}\n\nexport function createBoundedAsyncIterator<T>(\n  capacity: number,\n  onDispose: () => void,\n): {\n  iterator: AsyncDisposableIterator<T>\n  subscriber: AbortableSubscriber<T>\n} {\n  const buffer: T[] = []\n  const pullWaiters: Array<(result: IteratorResult<T>) => void> = []\n  const pushWaiters: Array<PendingPush<T>> = []\n  let closed = false\n  let disposed = false\n\n  const settlePush = (\n    waiter: PendingPush<T>,\n    outcome: { kind: 'resolve' } | { kind: 'reject'; error: Error },\n  ): void => {\n    if (waiter.settled) return\n    waiter.settled = true\n    waiter.signal.removeEventListener('abort', waiter.onAbort)\n    if (outcome.kind === 'resolve') {\n      waiter.resolve()\n    } else {\n      waiter.reject(outcome.error)\n    }\n  }\n\n  const shiftPushWaiter = (): PendingPush<T> | undefined => {\n    const waiter = pushWaiters.shift()\n    if (waiter) {\n      waiter.settled = true\n      waiter.signal.removeEventListener('abort', waiter.onAbort)\n    }\n    return waiter\n  }\n\n  const fillAvailableCapacity = (): void => {\n    while (!closed && buffer.length < capacity && pushWaiters.length > 0) {\n      const waiter = shiftPushWaiter()\n      if (!waiter) break\n      buffer.push(waiter.value)\n      waiter.resolve()\n    }\n  }\n\n  const releasePushWaiters = (): void => {\n    for (const waiter of pushWaiters.splice(0)) {\n      settlePush(waiter, { kind: 'resolve' })\n    }\n  }\n\n  const releasePullWaiters = (): void => {\n    for (const waiter of pullWaiters.splice(0)) {\n      waiter({ value: undefined, done: true })\n    }\n  }\n\n  const subscriber: AbortableSubscriber<T> = {\n    push(value, signal) {\n      if (closed) return Promise.resolve()\n      if (signal.aborted) return Promise.reject(toError(signal.reason))\n\n      const pullWaiter = pullWaiters.shift()\n      if (pullWaiter) {\n        pullWaiter({ value, done: false })\n        return Promise.resolve()\n      }\n\n      if (pushWaiters.length === 0 && buffer.length < capacity) {\n        buffer.push(value)\n        return Promise.resolve()\n      }\n\n      return new Promise<void>((resolve, reject) => {\n        const pending: PendingPush<T> = {\n          value,\n          resolve,\n          reject,\n          signal,\n          settled: false,\n          onAbort: () => {\n            const index = pushWaiters.indexOf(pending)\n            if (index !== -1) {\n              pushWaiters.splice(index, 1)\n            }\n            settlePush(pending, { kind: 'reject', error: toError(signal.reason) })\n          },\n        }\n        pushWaiters.push(pending)\n        signal.addEventListener('abort', pending.onAbort, { once: true })\n\n        if (signal.aborted) {\n          pending.onAbort()\n        }\n      })\n    },\n    close() {\n      if (closed) return\n      closed = true\n      releasePushWaiters()\n      releasePullWaiters()\n    },\n  }\n\n  const dispose = (): void => {\n    if (disposed) return\n    disposed = true\n    closed = true\n    buffer.length = 0\n    releasePushWaiters()\n    releasePullWaiters()\n    onDispose()\n  }\n\n  const iterator: AsyncDisposableIterator<T> = {\n    next(): Promise<IteratorResult<T>> {\n      if (disposed) {\n        return Promise.resolve({ value: undefined, done: true })\n      }\n\n      if (buffer.length > 0) {\n        const value = buffer.shift() as T\n        fillAvailableCapacity()\n        return Promise.resolve({ value, done: false })\n      }\n\n      const pending = shiftPushWaiter()\n      if (pending) {\n        pending.resolve()\n        return Promise.resolve({ value: pending.value, done: false })\n      }\n\n      if (closed) {\n        return Promise.resolve({ value: undefined, done: true })\n      }\n\n      return new Promise<IteratorResult<T>>((resolve) => pullWaiters.push(resolve))\n    },\n    return(): Promise<IteratorResult<T>> {\n      dispose()\n      return Promise.resolve({ value: undefined, done: true })\n    },\n    throw(error?: unknown): Promise<IteratorResult<T>> {\n      dispose()\n      return Promise.reject(error)\n    },\n    [Symbol.asyncIterator]() {\n      return iterator\n    },\n    [Symbol.asyncDispose](): Promise<void> {\n      dispose()\n      return Promise.resolve()\n    },\n  }\n\n  return { iterator, subscriber }\n}\n\nfunction toError(error: unknown): Error {\n  return error instanceof Error ? error : new Error(String(error))\n}\n","import { randomUUID } from 'node:crypto'\nimport { clonePersistedValue, persistedValuesEqual } from '../storage/codec'\nimport {\n  createBoundedAsyncIterator,\n  type AbortableSubscriber,\n} from './async-iterator'\nimport {\n  ConfigError,\n  DuplicateWorkflowError,\n  EarlyCompleteError,\n  IdempotencyConflictError,\n  LeaseExpiredError,\n  ParallelCompleteError,\n  RunCancelledError,\n  RunControlError,\n  StepTimeoutError,\n  WorkflowNotFoundError,\n} from './errors'\nimport type {\n  ClaimedRun,\n  PersistedValue,\n  RunInfo,\n  StorageAdapter,\n  WorkflowRun,\n} from './types'\nimport type { AnyWorkflow, StepDefinition, WorkflowInputMap } from './workflow'\n\n/**\n * A lifecycle event emitted during workflow execution.\n *\n * Consumed both by the {@link EngineHooks} callbacks and by {@link Engine.stream}.\n * Every event carries the owning `workflow` name so a single stream can fan out\n * across multiple workflows.\n */\nexport type EngineEvent =\n  | { readonly type: 'runStart'; readonly runId: string; readonly workflow: string }\n  | { readonly type: 'stepStart'; readonly runId: string; readonly workflow: string; readonly stepName: string }\n  | {\n      readonly type: 'stepComplete'\n      readonly runId: string\n      readonly workflow: string\n      readonly stepName: string\n      readonly output: PersistedValue\n      readonly attempts: number\n    }\n  | { readonly type: 'runComplete'; readonly runId: string; readonly workflow: string; readonly output: PersistedValue }\n  | { readonly type: 'runFailed'; readonly runId: string; readonly workflow: string; readonly stepName: string; readonly error: Error }\n\n/** Narrow {@link EngineEvent} to a single `type` (or union of types). */\nexport type EngineEventOf<T extends EngineEvent['type']> = Extract<EngineEvent, { type: T }>\n\n/**\n * Lifecycle hooks fired during workflow execution.\n *\n * Hooks may be synchronous or `async` — an async hook is awaited before the\n * engine proceeds, so it can apply backpressure or guarantee ordering. A hook\n * that throws (or rejects) never affects engine state; the error is swallowed.\n */\nexport interface EngineHooks {\n  onRunStart?: (event: EngineEventOf<'runStart'>) => void\n  onStepStart?: (event: EngineEventOf<'stepStart'>) => void\n  onStepComplete?: (event: EngineEventOf<'stepComplete'>) => void\n  onRunComplete?: (event: EngineEventOf<'runComplete'>) => void\n  onRunFailed?: (event: EngineEventOf<'runFailed'>) => void\n  /** Called when a background operation fails (scheduled enqueue, poll cycle). Without this hook, these errors are silently swallowed. */\n  onError?: (error: Error) => void\n}\n\n/** Options for {@link Engine.stream}. */\nexport interface StreamOptions {\n  /**\n   * Maximum number of events buffered before the engine pauses (backpressure).\n   * Defaults to `Infinity` — events buffer without bound and the engine never\n   * waits on the consumer. Set a finite value (e.g. `1`) to pace the engine\n   * against a slow consumer; the engine will not start the next unit of work\n   * until the consumer drains the buffer below this size. Set `0` for strict\n   * rendezvous delivery, where every event waits for a pending pull.\n   */\n  bufferSize?: number\n}\n\n/**\n * A pull-based, backpressure-aware stream of {@link EngineEvent}s.\n *\n * Implements `AsyncIterableIterator`, so it works directly with `for await`,\n * and `AsyncDisposable`, so it works with `await using`. Breaking out of a\n * `for await` loop (or disposing) unsubscribes from the engine automatically.\n */\nexport interface ResultStream<E extends EngineEvent = EngineEvent>\n  extends AsyncIterableIterator<E> {\n  [Symbol.asyncDispose](): Promise<void>\n}\n\n/** Configuration for {@link createEngine}. */\nexport interface EngineConfig<TWorkflows extends readonly AnyWorkflow[] = readonly AnyWorkflow[]> {\n  /** Storage backend for persisting runs and step results. */\n  storage: StorageAdapter\n  /** Workflows the engine can execute. */\n  workflows: TWorkflows\n  /** Optional lifecycle hooks. */\n  hooks?: EngineHooks\n  /** Maximum runs to process in parallel per tick (default: 1). */\n  concurrency?: number\n  /** How long a run's lease is valid before another engine can reclaim it (default: 30000). */\n  runLeaseDurationMs?: number\n  /** How often to renew the lease while a run is executing (default: leaseDuration / 3). */\n  heartbeatIntervalMs?: number\n}\n\n/** Options for `engine.enqueue()`. */\nexport interface EnqueueOptions {\n  /** Prevents duplicate runs. Same key + same input returns the existing run. Same key + different input throws. */\n  idempotencyKey?: string\n}\n\n/** The workflow engine. Connects workflows to storage and handles execution, polling, and scheduling. */\nexport interface Engine<TWorkflowMap extends Record<string, PersistedValue> = Record<string, PersistedValue>> {\n  /** Submit a workflow run. Type-safe: only accepts registered workflow names with matching input. */\n  enqueue<TName extends string & keyof TWorkflowMap>(\n    workflowName: TName,\n    input: TWorkflowMap[TName],\n    options?: EnqueueOptions,\n  ): Promise<WorkflowRun>\n  /** Get a run and its step results, or null if not found. */\n  getRunStatus(runId: string): Promise<RunInfo | null>\n  /** Cancel a pending or running workflow. Returns true if cancelled. */\n  cancel(runId: string): Promise<boolean>\n  /** Enqueue a workflow on a recurring interval. Returns a schedule ID. */\n  schedule<TName extends string & keyof TWorkflowMap>(\n    workflowName: TName,\n    input: TWorkflowMap[TName],\n    intervalMs: number,\n  ): string\n  /** Cancel a recurring schedule by ID. */\n  unschedule(scheduleId: string): boolean\n  /**\n   * Subscribe to a live, pull-based stream of execution events\n   * ({@link EngineEvent}). Use it to consume step/run results as they happen,\n   * with optional backpressure:\n   *\n   * ```ts\n   * for await (const event of engine.stream()) {\n   *   if (event.type === 'runComplete') process(event.output)\n   * }\n   * ```\n   *\n   * Each call returns an independent stream. Breaking out of the loop, or\n   * disposing the stream, unsubscribes automatically.\n   */\n  stream(options?: StreamOptions): ResultStream\n  /** Process one batch of pending runs. Useful for tests and CLI tools. */\n  tick(): Promise<void>\n  /** Initialize storage and start the polling loop. Call once at startup. */\n  start(pollIntervalMs?: number): Promise<void>\n  /** Stop the polling loop, clear all schedules, and wait for in-flight ticks to finish. */\n  stop(): Promise<void>\n}\n\ninterface ActiveRunState {\n  leaseId: string\n  runAbortController: AbortController\n  observerAbortController: AbortController\n  heartbeatTimer: ReturnType<typeof setInterval> | null\n  heartbeatInFlight: boolean\n}\n\n/**\n * Create a workflow engine that connects workflows to storage and handles execution.\n *\n * @example\n * ```ts\n * const engine = createEngine({\n *   storage: new SQLiteStorage('./reflow.db'),\n *   workflows: [myWorkflow],\n * })\n * await engine.start()\n * ```\n */\nexport function createEngine<const TWorkflows extends readonly AnyWorkflow[]>(\n  config: EngineConfig<TWorkflows>,\n): Engine<WorkflowInputMap<TWorkflows>> {\n  const {\n    storage,\n    workflows,\n    hooks,\n    concurrency = 1,\n    runLeaseDurationMs = 30_000,\n    heartbeatIntervalMs = defaultHeartbeatInterval(runLeaseDurationMs),\n  } = config\n\n  if (!Number.isInteger(concurrency) || concurrency < 1) {\n    throw new ConfigError('Engine concurrency must be a positive integer')\n  }\n\n  if (!Number.isFinite(runLeaseDurationMs) || runLeaseDurationMs <= 0) {\n    throw new ConfigError('Engine runLeaseDurationMs must be a positive number')\n  }\n\n  if (!Number.isFinite(heartbeatIntervalMs) || heartbeatIntervalMs <= 0) {\n    throw new ConfigError('Engine heartbeatIntervalMs must be a positive number')\n  }\n\n  if (heartbeatIntervalMs >= runLeaseDurationMs) {\n    throw new ConfigError('Engine heartbeatIntervalMs must be smaller than runLeaseDurationMs')\n  }\n\n  const registry = new Map<string, AnyWorkflow>()\n  const schedules = new Map<string, ReturnType<typeof setInterval>>()\n  const activeRuns = new Map<string, ActiveRunState>()\n  const subscribers = new Set<AbortableSubscriber<EngineEvent>>()\n  let running = false\n  let timer: ReturnType<typeof setInterval> | null = null\n  let tickInFlight = false\n  let tickPromise: Promise<void> | null = null\n  let stopGeneration = 0\n\n  for (const wf of workflows) {\n    if (registry.has(wf.name)) {\n      throw new DuplicateWorkflowError(wf.name)\n    }\n\n    registry.set(wf.name, wf)\n  }\n\n  const workflowNames = Array.from(registry.keys())\n\n  async function enqueue(\n    workflowName: string,\n    input: PersistedValue,\n    options?: EnqueueOptions,\n  ): Promise<WorkflowRun> {\n    const wf = registry.get(workflowName)\n    if (!wf) throw new WorkflowNotFoundError(workflowName)\n\n    const idempotencyKey = normalizeIdempotencyKey(options?.idempotencyKey)\n    const parsedInput = wf.parseInput(input)\n    const now = Date.now()\n\n    const run: WorkflowRun = {\n      id: randomUUID(),\n      workflow: workflowName,\n      input: parsedInput,\n      idempotencyKey,\n      status: 'pending',\n      createdAt: now,\n      updatedAt: now,\n    }\n\n    const { run: storedRun, created } = await storage.createRun(run)\n\n    if (!created && idempotencyKey && !persistedValuesEqual(storedRun.input, parsedInput)) {\n      throw new IdempotencyConflictError(workflowName, idempotencyKey)\n    }\n\n    return storedRun\n  }\n\n  async function getRunStatus(runId: string): Promise<RunInfo | null> {\n    const run = await storage.getRun(runId)\n    if (!run) return null\n\n    const steps = await storage.getStepResults(runId)\n    return { run, steps }\n  }\n\n  /**\n   * Dispatch a lifecycle event to the user hook and every active stream, then\n   * wait for them all to settle. Awaiting here is what lets an `async` hook or a\n   * backpressured stream pace the engine. Neither a throwing hook nor a stream\n   * may affect engine state, so all errors are contained.\n   */\n  async function emit(event: EngineEvent, signal: AbortSignal): Promise<void> {\n    try {\n      await runWithSignal(\n        () => Promise.resolve(dispatchHook(event)).then(noop),\n        signal,\n      )\n    } catch {\n      if (signal.aborted) {\n        throw toError(signal.reason)\n      }\n      // Hooks are observers and must not affect engine state.\n    }\n\n    if (subscribers.size === 0) {\n      return\n    }\n\n    const deliveries = Array.from(\n      subscribers,\n      (subscriber) => subscriber.push(cloneEngineEvent(event), signal),\n    )\n\n    try {\n      await runWithSignal(\n        () => Promise.allSettled(deliveries).then(noop),\n        signal,\n      )\n    } catch {\n      if (signal.aborted) {\n        throw toError(signal.reason)\n      }\n      // Stream delivery is observational and must not affect engine state.\n    }\n  }\n\n  function dispatchHook(event: EngineEvent): unknown {\n    switch (event.type) {\n      case 'runStart':\n        return hooks?.onRunStart?.({ ...event })\n      case 'stepStart':\n        return hooks?.onStepStart?.({ ...event })\n      case 'stepComplete':\n        return hooks?.onStepComplete?.({\n          ...event,\n          output: clonePersistedValue(event.output, 'Step hook output'),\n        })\n      case 'runComplete':\n        return hooks?.onRunComplete?.({\n          ...event,\n          output: clonePersistedValue(event.output, 'Run hook output'),\n        })\n      case 'runFailed':\n        return hooks?.onRunFailed?.({\n          ...event,\n          error: cloneError(event.error),\n        })\n    }\n  }\n\n  /** Report a background error to `onError`, swallowing any error it raises. */\n  function reportError(error: unknown): void {\n    const err = error instanceof Error ? error : new Error(String(error))\n    void (async () => {\n      try {\n        await hooks?.onError?.(err)\n      } catch { /* onError must not throw */ }\n    })()\n  }\n\n  function createStream(options?: StreamOptions): ResultStream {\n    const capacity = options?.bufferSize ?? Number.POSITIVE_INFINITY\n    if (\n      capacity !== Number.POSITIVE_INFINITY &&\n      (!Number.isInteger(capacity) || capacity < 0)\n    ) {\n      throw new ConfigError('Stream bufferSize must be a non-negative integer or Infinity')\n    }\n\n    let subscriber!: AbortableSubscriber<EngineEvent>\n    const channel = createBoundedAsyncIterator<EngineEvent>(\n      capacity,\n      () => subscribers.delete(subscriber),\n    )\n    subscriber = channel.subscriber\n    subscribers.add(subscriber)\n    return channel.iterator\n  }\n\n  async function executeRun(run: ClaimedRun): Promise<void> {\n    const wf = registry.get(run.workflow)\n    if (!wf) return\n\n    const activeRun = registerActiveRun(run)\n    const observerSignal = activeRun.observerAbortController.signal\n\n    try {\n      const currentRun = await storage.getRun(run.id)\n      if (!currentRun || currentRun.status !== 'running') {\n        return\n      }\n\n      await emit({ type: 'runStart', runId: run.id, workflow: run.workflow }, observerSignal)\n\n      const existingSteps = await storage.getStepResults(run.id)\n      const completedMap = new Map(existingSteps.map((step) => [step.name, step]))\n      let prev: PersistedValue = undefined\n      const stepsAccumulator: Record<string, PersistedValue> = {}\n\n      for (const unit of wf.executionUnits) {\n        if (unit.kind === 'step') {\n          const stepDef = unit.definition\n          if (activeRun.runAbortController.signal.aborted) {\n            const latestRun = await storage.getRun(run.id)\n            if (!latestRun || latestRun.status === 'cancelled') {\n              return\n            }\n          }\n\n          const existing = completedMap.get(stepDef.name)\n          if (existing?.status === 'completed-early') {\n            // This step called complete() in a previous execution — finish the run\n            await emit({\n              type: 'stepComplete',\n              runId: run.id,\n              workflow: run.workflow,\n              stepName: stepDef.name,\n              output: existing.output,\n              attempts: existing.attempts,\n            }, observerSignal)\n\n            const completed = await storage.updateClaimedRunStatus(run.id, run.leaseId, 'completed')\n            if (!completed) {\n              throw new LeaseExpiredError(run.id)\n            }\n\n            await emit(\n              { type: 'runComplete', runId: run.id, workflow: run.workflow, output: existing.output },\n              observerSignal,\n            )\n\n            return\n          }\n          if (existing?.status === 'completed') {\n            prev = existing.output\n            stepsAccumulator[stepDef.name] = structuredClone(existing.output)\n            continue\n          }\n\n          const frozenSteps = snapshotSteps(stepsAccumulator)\n\n          try {\n            await emit(\n              { type: 'stepStart', runId: run.id, workflow: run.workflow, stepName: stepDef.name },\n              observerSignal,\n            )\n\n            const outcome = await executeStep(run, activeRun, stepDef, prev, frozenSteps)\n\n            if (outcome.kind === 'failed') {\n              // A control-flow abort (cancel / engine stop / lease loss) can land\n              // on an await point between steps — including a backpressured stream\n              // emit. When it does, executeStep reports a synthetic failure for a\n              // step that never really ran. That is a side effect of the abort, not\n              // a real failure: leave the run untouched (status stays as-is, so a\n              // stopped or lease-lost run remains reclaimable) instead of marking\n              // it failed. A non-control abort reason (e.g. a heartbeat storage\n              // error) is a genuine failure and still falls through below.\n              if (\n                activeRun.runAbortController.signal.aborted &&\n                activeRun.runAbortController.signal.reason instanceof RunControlError\n              ) {\n                return\n              }\n\n              // Persist the failed step result\n              const now = Date.now()\n              const saved = await storage.saveStepResult({\n                id: randomUUID(),\n                runId: run.id,\n                name: stepDef.name,\n                status: 'failed',\n                output: null,\n                error: outcome.error.message,\n                attempts: outcome.attempts,\n                createdAt: now,\n                updatedAt: now,\n              }, run.leaseId)\n\n              if (!saved) {\n                throw new LeaseExpiredError(run.id)\n              }\n\n              throw outcome.error\n            }\n\n            // Unified success path for both normal and early completion\n            const now = Date.now()\n            const saved = await storage.saveStepResult({\n              id: randomUUID(),\n              runId: run.id,\n              name: stepDef.name,\n              status: outcome.kind === 'early-complete' ? 'completed-early' : 'completed',\n              output: outcome.output,\n              error: null,\n              attempts: outcome.attempts,\n              createdAt: now,\n              updatedAt: now,\n            }, run.leaseId)\n\n            if (!saved) {\n              throw new LeaseExpiredError(run.id)\n            }\n\n            await emit({\n              type: 'stepComplete',\n              runId: run.id,\n              workflow: run.workflow,\n              stepName: stepDef.name,\n              output: outcome.output,\n              attempts: outcome.attempts,\n            }, observerSignal)\n\n            if (outcome.kind === 'early-complete') {\n              const completed = await storage.updateClaimedRunStatus(run.id, run.leaseId, 'completed')\n              if (!completed) {\n                throw new LeaseExpiredError(run.id)\n              }\n\n              await emit(\n                { type: 'runComplete', runId: run.id, workflow: run.workflow, output: outcome.output },\n                observerSignal,\n              )\n\n              return\n            }\n\n            prev = outcome.output\n            stepsAccumulator[stepDef.name] = structuredClone(prev)\n          } catch (error) {\n            const err = error instanceof Error ? error : new Error(String(error))\n\n            if (err instanceof EarlyCompleteError) {\n              throw new Error(`EarlyCompleteError escaped executeStep for step \"${stepDef.name}\"`)\n            }\n\n            if (err instanceof RunControlError) {\n              return\n            }\n\n            if (activeRun.runAbortController.signal.aborted) {\n              const currentRun = await storage.getRun(run.id)\n              if (!currentRun || currentRun.status === 'cancelled') {\n                return\n              }\n            }\n\n            const failed = await storage.updateClaimedRunStatus(run.id, run.leaseId, 'failed')\n            if (!failed) {\n              return\n            }\n\n            await emit(\n              { type: 'runFailed', runId: run.id, workflow: run.workflow, stepName: stepDef.name, error: err },\n              observerSignal,\n            )\n\n            if (wf.failureHandler) {\n              try {\n                await wf.failureHandler({\n                  error: err,\n                  stepName: stepDef.name,\n                  input: run.input,\n                })\n              } catch { /* onFailure must not affect engine state */ }\n            }\n\n            return\n          }\n        } else {\n          const result = await executeParallelGroup(run, activeRun, unit.branches, prev, stepsAccumulator, completedMap)\n          if (result.kind === 'skipped-cancelled') {\n            return\n          }\n          if (result.kind === 'failed') {\n            const failed = await storage.updateClaimedRunStatus(run.id, run.leaseId, 'failed')\n            if (!failed) {\n              return\n            }\n\n            await emit(\n              { type: 'runFailed', runId: run.id, workflow: run.workflow, stepName: result.branchName, error: result.error },\n              observerSignal,\n            )\n\n            if (wf.failureHandler) {\n              try {\n                await wf.failureHandler({\n                  error: result.error,\n                  stepName: result.branchName,\n                  input: run.input,\n                })\n              } catch { /* onFailure must not affect engine state */ }\n            }\n\n            return\n          }\n          prev = result.merged\n        }\n      }\n\n      const latestRun = await storage.getRun(run.id)\n      if (!latestRun || latestRun.status === 'cancelled') {\n        return\n      }\n\n      const completed = await storage.updateClaimedRunStatus(run.id, run.leaseId, 'completed')\n      if (!completed) {\n        return\n      }\n\n      await emit(\n        { type: 'runComplete', runId: run.id, workflow: run.workflow, output: prev },\n        observerSignal,\n      )\n    } catch (error) {\n      if (!(error instanceof RunControlError)) {\n        throw error\n      }\n    } finally {\n      cleanupActiveRun(run.id)\n    }\n  }\n\n  type StepOutcome =\n    | { kind: 'completed'; output: PersistedValue; attempts: number }\n    | { kind: 'early-complete'; output: PersistedValue; attempts: number }\n    | { kind: 'failed'; error: Error; attempts: number }\n\n  async function executeStep(\n    run: ClaimedRun,\n    activeRun: ActiveRunState,\n    stepDef: StepDefinition,\n    prev: PersistedValue,\n    steps: Record<string, PersistedValue>,\n  ): Promise<StepOutcome> {\n    const maxAttempts = stepDef.retry?.maxAttempts ?? 1\n    if (maxAttempts < 1) {\n      throw new ConfigError(`Step \"${stepDef.name}\" retry maxAttempts must be at least 1`)\n    }\n    const backoff = stepDef.retry?.backoff ?? 'linear'\n    const initialDelay = stepDef.retry?.initialDelayMs ?? 1000\n    const timeoutMs = stepDef.timeoutMs ?? stepDef.retry?.timeoutMs\n\n    let lastError: Error | null = null\n\n    for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n      // Bail out of further retry attempts once the run/group signal is aborted.\n      // A handler is not re-entered (runWithSignal short-circuits), but iterating\n      // the loop just to reject again wastes work and confuses metrics.\n      if (activeRun.runAbortController.signal.aborted) {\n        break\n      }\n\n      const attemptSignal = createAttemptSignal(activeRun.runAbortController.signal, timeoutMs)\n\n      try {\n        const complete = (value?: PersistedValue): never => {\n          throw new EarlyCompleteError(value)\n        }\n        const rawOutput = await runWithSignal(\n          () => stepDef.handler({ input: run.input, prev, signal: attemptSignal.signal, complete, steps }),\n          attemptSignal.signal,\n        )\n        const output: PersistedValue = rawOutput === undefined ? undefined : rawOutput\n\n        return { kind: 'completed', output, attempts: attempt }\n      } catch (error) {\n        if (error instanceof EarlyCompleteError) {\n          const earlyOutput: PersistedValue = error.value === undefined ? undefined : error.value\n          return { kind: 'early-complete', output: earlyOutput, attempts: attempt }\n        }\n\n        const err = error instanceof Error ? error : new Error(String(error))\n\n        if (err instanceof RunControlError) {\n          throw err\n        }\n\n        lastError = err\n\n        if (attempt < maxAttempts) {\n          const delay = backoff === 'exponential'\n            ? initialDelay * Math.pow(2, attempt - 1)\n            : initialDelay * attempt\n\n          if (delay > 0) {\n            await delayWithSignal(delay, activeRun.runAbortController.signal)\n          }\n        }\n      } finally {\n        attemptSignal.cleanup()\n      }\n    }\n\n    // RunControlError is rethrown inside the loop; if we reach here, lastError is a\n    // regular failure (or null when the signal was aborted before any attempt ran).\n    return { kind: 'failed', error: lastError ?? new Error('Unknown error'), attempts: maxAttempts }\n  }\n\n  type ParallelGroupResult =\n    | { kind: 'completed'; merged: Record<string, PersistedValue> }\n    | { kind: 'skipped-cancelled' }\n    | { kind: 'failed'; branchName: string; error: Error }\n\n  async function executeParallelGroup(\n    run: ClaimedRun,\n    activeRun: ActiveRunState,\n    branches: readonly StepDefinition[],\n    prev: PersistedValue,\n    stepsAccumulator: Record<string, PersistedValue>,\n    completedMap: Map<string, { id: string; status: string; output: PersistedValue; attempts: number }>,\n  ): Promise<ParallelGroupResult> {\n    if (activeRun.runAbortController.signal.aborted) {\n      const latestRun = await storage.getRun(run.id)\n      if (!latestRun || latestRun.status === 'cancelled') {\n        return { kind: 'skipped-cancelled' }\n      }\n    }\n\n    // Crash-recovery: any branch already persisted as 'completed' is reused.\n    // Failed records do not count — they get retried fresh, matching sequential semantics.\n    const merged: Record<string, PersistedValue> = {}\n    const pendingBranches: StepDefinition[] = []\n    for (const branchDef of branches) {\n      const existing = completedMap.get(branchDef.name)\n      if (existing?.status === 'completed') {\n        merged[branchDef.name] = existing.output\n        stepsAccumulator[branchDef.name] = structuredClone(existing.output)\n      } else {\n        pendingBranches.push(branchDef)\n      }\n    }\n\n    if (pendingBranches.length === 0) {\n      return { kind: 'completed', merged }\n    }\n\n    const frozenSteps = snapshotSteps(stepsAccumulator)\n\n    const groupAbort = new AbortController()\n    // Track which branch was the *original* failure that caused the group to abort.\n    // Siblings that fail because they observed the abort are downstream effects, not\n    // the underlying cause — distinguishing this keeps onRunFailed accurate.\n    let causeBranch: BranchFailedError | null = null\n    const onRunAbort = () => {\n      if (!groupAbort.signal.aborted) {\n        groupAbort.abort(activeRun.runAbortController.signal.reason)\n      }\n    }\n    if (activeRun.runAbortController.signal.aborted) {\n      groupAbort.abort(activeRun.runAbortController.signal.reason)\n    } else {\n      activeRun.runAbortController.signal.addEventListener('abort', onRunAbort, { once: true })\n    }\n\n    try {\n      for (const branchDef of pendingBranches) {\n        await emit(\n          { type: 'stepStart', runId: run.id, workflow: run.workflow, stepName: branchDef.name },\n          activeRun.observerAbortController.signal,\n        )\n      }\n\n      const groupActiveRun: ActiveRunState = {\n        ...activeRun,\n        runAbortController: groupAbort,\n      }\n\n      // Run all pending branches; collect both successes and failures so siblings\n      // get a chance to settle (allSettled, not all) before we tear down.\n      const settled = await Promise.allSettled(\n        pendingBranches.map(async (branchDef) => {\n          const guardedHandler: StepDefinition['handler'] = (ctx) => {\n            const guardedComplete = (): never => {\n              throw new ParallelCompleteError(branchDef.name)\n            }\n            return branchDef.handler({ ...ctx, complete: guardedComplete })\n          }\n\n          const guardedDef: StepDefinition = { ...branchDef, handler: guardedHandler }\n          const outcome = await executeStep(run, groupActiveRun, guardedDef, prev, frozenSteps)\n\n          // `outcome.kind === 'early-complete'` is unreachable: guardedComplete throws\n          // ParallelCompleteError (a regular error) before EarlyCompleteError can be\n          // raised, so executeStep returns 'completed' or 'failed' for parallel branches.\n          if (outcome.kind === 'failed') {\n            const failure = new BranchFailedError(branchDef.name, outcome.error, outcome.attempts)\n            if (!groupAbort.signal.aborted) {\n              causeBranch = failure\n              groupAbort.abort(outcome.error)\n            }\n            throw failure\n          }\n\n          return { name: branchDef.name, output: outcome.output, attempts: outcome.attempts }\n        }),\n      )\n\n      // If the run itself was aborted by a control-flow signal while branches were\n      // running (cancel, engine stop, or lease loss), surface that before reporting\n      // branch failures. A branch that failed because it observed the run-level\n      // abort is a downstream effect, not the cause — reporting it would mark a\n      // stopped/reclaimable run as failed. A non-control abort (e.g. a heartbeat\n      // storage error) is a genuine failure and still falls through below.\n      if (\n        activeRun.runAbortController.signal.aborted &&\n        activeRun.runAbortController.signal.reason instanceof RunControlError\n      ) {\n        return { kind: 'skipped-cancelled' }\n      }\n\n      // Prefer the branch that actually caused the abort; only fall back to scanning\n      // settled when no cause was recorded (e.g. group aborted from outside the loop).\n      let firstFailure: BranchFailedError | null = causeBranch\n      if (!firstFailure) {\n        for (const result of settled) {\n          if (result.status === 'rejected') {\n            const err = result.reason instanceof Error ? result.reason : new Error(String(result.reason))\n            if (err instanceof RunControlError) {\n              return { kind: 'skipped-cancelled' }\n            }\n            if (err instanceof BranchFailedError) {\n              firstFailure = err\n              break\n            }\n            // Defensive: wrap unknown error as branch failure on first pending branch.\n            firstFailure = new BranchFailedError(pendingBranches[0].name, err, 1)\n            break\n          }\n        }\n      }\n\n      if (firstFailure) {\n        // Persist the failed step result. Reuse the existing row id so a retry upserts\n        // in place rather than appending a duplicate. If the lease is lost mid-write,\n        // we still report the failure — the outer code will no-op the run-status\n        // update because the same lease check will fail there.\n        const failedBranch = firstFailure.branchName\n        const existingRow = completedMap.get(failedBranch)\n        const now = Date.now()\n        await storage.saveStepResult({\n          id: existingRow?.id ?? randomUUID(),\n          runId: run.id,\n          name: failedBranch,\n          status: 'failed',\n          output: null,\n          error: firstFailure.branchError.message,\n          attempts: firstFailure.attempts,\n          createdAt: now,\n          updatedAt: now,\n        }, run.leaseId)\n\n        return { kind: 'failed', branchName: failedBranch, error: firstFailure.branchError }\n      }\n\n      // All pending branches succeeded — persist their results and fire complete hooks.\n      for (const result of settled) {\n        if (result.status !== 'fulfilled') continue\n        const branchResult = result.value\n        const existingRow = completedMap.get(branchResult.name)\n        const now = Date.now()\n        const saved = await storage.saveStepResult({\n          id: existingRow?.id ?? randomUUID(),\n          runId: run.id,\n          name: branchResult.name,\n          status: 'completed',\n          output: branchResult.output,\n          error: null,\n          attempts: branchResult.attempts,\n          createdAt: now,\n          updatedAt: now,\n        }, run.leaseId)\n\n        if (!saved) {\n          throw new LeaseExpiredError(run.id)\n        }\n\n        await emit({\n          type: 'stepComplete',\n          runId: run.id,\n          workflow: run.workflow,\n          stepName: branchResult.name,\n          output: branchResult.output,\n          attempts: branchResult.attempts,\n        }, activeRun.observerAbortController.signal)\n\n        stepsAccumulator[branchResult.name] = structuredClone(branchResult.output)\n        merged[branchResult.name] = branchResult.output\n      }\n\n      return { kind: 'completed', merged }\n    } catch (error) {\n      // Promise.allSettled above swallows per-branch failures, so this catch only\n      // fires for LeaseExpiredError thrown during success-path persistence.\n      const err = error instanceof Error ? error : new Error(String(error))\n\n      if (err instanceof RunControlError) {\n        return { kind: 'skipped-cancelled' }\n      }\n\n      return { kind: 'failed', branchName: pendingBranches[0].name, error: err }\n    } finally {\n      activeRun.runAbortController.signal.removeEventListener('abort', onRunAbort)\n    }\n  }\n\n\n  async function cancel(runId: string): Promise<boolean> {\n    const run = await storage.getRun(runId)\n    if (!run || run.status === 'completed' || run.status === 'failed' || run.status === 'cancelled') {\n      return false\n    }\n\n    const cancelled = await storage.updateRunStatus(runId, 'cancelled')\n    if (cancelled) {\n      abortActiveRun(runId, new RunCancelledError(runId))\n    }\n\n    return cancelled\n  }\n\n  function schedule(\n    workflowName: string,\n    input: PersistedValue,\n    intervalMs: number,\n  ): string {\n    if (!Number.isFinite(intervalMs) || intervalMs <= 0) {\n      throw new ConfigError('Schedule intervalMs must be a positive number')\n    }\n\n    const wf = registry.get(workflowName)\n    if (!wf) throw new WorkflowNotFoundError(workflowName)\n\n    const parsedInput = wf.parseInput(input)\n    const scheduleId = randomUUID()\n    const interval = setInterval(() => {\n      void enqueue(workflowName, parsedInput).catch(reportError)\n    }, intervalMs)\n\n    schedules.set(scheduleId, interval)\n    return scheduleId\n  }\n\n  function unschedule(scheduleId: string): boolean {\n    const interval = schedules.get(scheduleId)\n    if (!interval) return false\n\n    clearInterval(interval)\n    schedules.delete(scheduleId)\n    return true\n  }\n\n  async function tick(): Promise<void> {\n    if (registry.size === 0 || tickInFlight) {\n      return\n    }\n\n    const generation = stopGeneration\n    tickInFlight = true\n    const promise = (async () => {\n      try {\n        const staleBefore = Date.now() - runLeaseDurationMs\n        const runs: ClaimedRun[] = []\n\n        for (let index = 0; index < concurrency; index++) {\n          const run = await storage.claimNextRun(workflowNames, staleBefore)\n          if (!run) {\n            break\n          }\n\n          runs.push(run)\n        }\n\n        if (generation !== stopGeneration) {\n          return\n        }\n\n        await Promise.all(runs.map((run) => executeRun(run)))\n      } finally {\n        tickInFlight = false\n        tickPromise = null\n      }\n    })()\n    tickPromise = promise\n    await promise\n  }\n\n  async function start(pollIntervalMs = 1000): Promise<void> {\n    if (!Number.isFinite(pollIntervalMs) || pollIntervalMs <= 0) {\n      throw new ConfigError('Engine pollIntervalMs must be a positive number')\n    }\n\n    await storage.initialize()\n    if (running) {\n      return\n    }\n\n    running = true\n\n    const triggerPoll = () => {\n      void runPollCycle().catch(reportError)\n    }\n\n    triggerPoll()\n    timer = setInterval(triggerPoll, pollIntervalMs)\n  }\n\n  async function runPollCycle(): Promise<void> {\n    if (!running) {\n      return\n    }\n\n    await tick()\n  }\n\n  async function stop(): Promise<void> {\n    stopGeneration++\n    running = false\n\n    if (timer) {\n      clearInterval(timer)\n      timer = null\n    }\n\n    for (const [scheduleId, interval] of schedules) {\n      clearInterval(interval)\n      schedules.delete(scheduleId)\n    }\n\n    for (const [runId] of activeRuns) {\n      abortActiveRun(runId, new RunControlError('Engine stopped'))\n      cleanupActiveRun(runId)\n    }\n\n    // End all streams and unblock any producer paused on backpressure, so a\n    // pending tick can settle instead of deadlocking on a consumer that is gone.\n    for (const subscriber of subscribers) {\n      subscriber.close()\n    }\n    subscribers.clear()\n\n    if (tickPromise) {\n      await tickPromise.catch(noop)\n    }\n  }\n\n  function registerActiveRun(run: ClaimedRun): ActiveRunState {\n    const existing = activeRuns.get(run.id)\n    if (existing) {\n      cleanupActiveRun(run.id)\n    }\n\n    const activeRun: ActiveRunState = {\n      leaseId: run.leaseId,\n      runAbortController: new AbortController(),\n      observerAbortController: new AbortController(),\n      heartbeatTimer: null,\n      heartbeatInFlight: false,\n    }\n\n    activeRuns.set(run.id, activeRun)\n    startHeartbeat(run, activeRun)\n    return activeRun\n  }\n\n  function startHeartbeat(run: ClaimedRun, activeRun: ActiveRunState): void {\n    const sendHeartbeat = async () => {\n      if (activeRun.heartbeatInFlight || activeRun.runAbortController.signal.aborted) {\n        return\n      }\n\n      activeRun.heartbeatInFlight = true\n\n      try {\n        const ok = await storage.heartbeatRun(run.id, activeRun.leaseId)\n        if (!ok) {\n          abortActiveRun(run.id, new LeaseExpiredError(run.id))\n        }\n      } catch (error) {\n        abortActiveRun(run.id, error instanceof Error ? error : new Error(String(error)))\n      } finally {\n        activeRun.heartbeatInFlight = false\n      }\n    }\n\n    activeRun.heartbeatTimer = setInterval(() => {\n      void sendHeartbeat()\n    }, heartbeatIntervalMs)\n  }\n\n  function cleanupActiveRun(runId: string): void {\n    const activeRun = activeRuns.get(runId)\n    if (!activeRun) {\n      return\n    }\n\n    if (activeRun.heartbeatTimer) {\n      clearInterval(activeRun.heartbeatTimer)\n    }\n\n    activeRuns.delete(runId)\n  }\n\n  function abortActiveRun(runId: string, reason: Error): void {\n    const activeRun = activeRuns.get(runId)\n    if (!activeRun) {\n      return\n    }\n\n    if (!activeRun.runAbortController.signal.aborted) {\n      activeRun.runAbortController.abort(reason)\n    }\n\n    if (\n      reason instanceof RunControlError &&\n      !activeRun.observerAbortController.signal.aborted\n    ) {\n      activeRun.observerAbortController.abort(reason)\n    }\n  }\n\n  return {\n    enqueue,\n    getRunStatus,\n    cancel,\n    schedule,\n    unschedule,\n    stream: createStream,\n    tick,\n    start,\n    stop,\n  } as Engine<WorkflowInputMap<TWorkflows>>\n}\n\nfunction cloneEngineEvent(event: EngineEvent): EngineEvent {\n  switch (event.type) {\n    case 'stepComplete':\n      return {\n        ...event,\n        output: clonePersistedValue(event.output, 'Step event output'),\n      }\n    case 'runComplete':\n      return {\n        ...event,\n        output: clonePersistedValue(event.output, 'Run event output'),\n      }\n    case 'runFailed':\n      return {\n        ...event,\n        error: cloneError(event.error),\n      }\n    default:\n      return { ...event }\n  }\n}\n\nfunction cloneError(error: Error): Error {\n  return Object.create(\n    Object.getPrototypeOf(error),\n    Object.getOwnPropertyDescriptors(error),\n  ) as Error\n}\n\nfunction runWithSignal<T>(\n  promiseFactory: () => Promise<T>,\n  signal: AbortSignal,\n): Promise<T> {\n  if (signal.aborted) {\n    return Promise.reject(toError(signal.reason))\n  }\n\n  return new Promise<T>((resolve, reject) => {\n    const onAbort = () => {\n      cleanup()\n      reject(toError(signal.reason))\n    }\n\n    const cleanup = () => {\n      signal.removeEventListener('abort', onAbort)\n    }\n\n    signal.addEventListener('abort', onAbort, { once: true })\n\n    Promise.resolve()\n      .then(promiseFactory)\n      .then(\n        (value) => {\n          cleanup()\n          resolve(value)\n        },\n        (error) => {\n          cleanup()\n          reject(error)\n        },\n      )\n  })\n}\n\nfunction createAttemptSignal(\n  runSignal: AbortSignal,\n  timeoutMs?: number,\n): { signal: AbortSignal; cleanup: () => void } {\n  const controller = new AbortController()\n  const cleanups: Array<() => void> = []\n\n  const forwardAbort = (reason: unknown) => {\n    if (!controller.signal.aborted) {\n      controller.abort(toError(reason))\n    }\n  }\n\n  if (runSignal.aborted) {\n    forwardAbort(runSignal.reason)\n  } else {\n    const onRunAbort = () => forwardAbort(runSignal.reason)\n    runSignal.addEventListener('abort', onRunAbort, { once: true })\n    cleanups.push(() => runSignal.removeEventListener('abort', onRunAbort))\n  }\n\n  if (timeoutMs) {\n    const timer = setTimeout(() => {\n      forwardAbort(new StepTimeoutError(timeoutMs))\n    }, timeoutMs)\n    cleanups.push(() => clearTimeout(timer))\n  }\n\n  return {\n    signal: controller.signal,\n    cleanup: () => {\n      for (const cleanup of cleanups) {\n        cleanup()\n      }\n    },\n  }\n}\n\nfunction delayWithSignal(ms: number, signal: AbortSignal): Promise<void> {\n  if (signal.aborted) {\n    return Promise.reject(toError(signal.reason))\n  }\n\n  return new Promise<void>((resolve, reject) => {\n    const timer = setTimeout(() => {\n      cleanup()\n      resolve()\n    }, ms)\n\n    const onAbort = () => {\n      cleanup()\n      reject(toError(signal.reason))\n    }\n\n    const cleanup = () => {\n      clearTimeout(timer)\n      signal.removeEventListener('abort', onAbort)\n    }\n\n    signal.addEventListener('abort', onAbort, { once: true })\n  })\n}\n\nfunction normalizeIdempotencyKey(idempotencyKey?: string): string | null {\n  if (idempotencyKey === undefined) {\n    return null\n  }\n\n  if (idempotencyKey.length === 0) {\n    throw new ConfigError('Enqueue idempotencyKey must not be empty')\n  }\n\n  return idempotencyKey\n}\n\nfunction defaultHeartbeatInterval(runLeaseDurationMs: number): number {\n  return Math.max(1, Math.min(runLeaseDurationMs - 1, Math.floor(runLeaseDurationMs / 3)))\n}\n\nfunction toError(error: unknown): Error {\n  return error instanceof Error ? error : new Error(String(error))\n}\n\nfunction noop() {}\n\nfunction snapshotSteps(accumulator: Record<string, PersistedValue>): Readonly<Record<string, PersistedValue>> {\n  return deepFreeze(structuredClone(accumulator))\n}\n\nfunction deepFreeze<T extends Record<string, unknown>>(obj: T): T {\n  Object.freeze(obj)\n  for (const value of Object.values(obj)) {\n    if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {\n      deepFreeze(value as Record<string, unknown>)\n    }\n  }\n  return obj\n}\n\n/**\n * Carries branch metadata (name, original error, attempts) through Promise.all rejections.\n * @internal Not exported from the public API.\n */\nclass BranchFailedError extends Error {\n  constructor(\n    public readonly branchName: string,\n    public readonly branchError: Error,\n    public readonly attempts: number,\n  ) {\n    super(branchError.message)\n    this.name = 'BranchFailedError'\n  }\n}\n"],"mappings":"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"}