@dudousxd/nestjs-durable-core 0.32.1 → 0.33.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/queue.ts","../src/admission.ts","../src/duration.ts","../src/backoff.ts","../src/step-logger.ts","../src/protocol.ts","../src/checkpoints.ts","../src/errors.ts","../src/entities.ts","../src/event-accumulators.ts","../src/events.ts","../src/singleton-gate.ts","../src/transport-pool.ts","../src/completion.ts","../src/workflow-ref.ts","../src/workflow-ctx.ts","../src/engine.ts","../src/remote-step-factory.ts","../src/remote-workflow-executor.ts","../src/codec-state-store.ts","../src/metrics.ts","../src/scheduler.ts","../src/search-attributes.ts","../src/tokens.ts","../src/testing/in-memory-state-store.ts","../src/testing/in-memory-transport.ts"],"sourcesContent":["export * from './admission';\nexport * from './duration';\nexport * from './engine';\nexport * from './entities';\nexport * from './errors';\nexport * from './event-accumulators';\nexport * from './interfaces';\nexport * from './protocol';\nexport * from './queue';\nexport * from './remote-step-factory';\nexport * from './remote-workflow-executor';\nexport * from './codec-state-store';\nexport * from './events';\nexport * from './metrics';\nexport * from './scheduler';\nexport * from './search-attributes';\nexport * from './tokens';\nexport * from './workflow-ref';\nexport { InMemoryStateStore } from './testing/in-memory-state-store';\nexport { InMemoryTransport } from './testing/in-memory-transport';\n","/**\n * Flow control for remote steps. A queue caps how much work `ctx.call(step, input, { queue })`\n * admits at once — a concurrency limit and/or a fixed-window rate limit. When a call can't be\n * admitted it doesn't dispatch: the run re-suspends with a near-future wake time, and the timer\n * poller re-tries admission later — so flow control is durable (survives crashes) without holding\n * the run in memory.\n *\n * Accounting is per engine instance (the DBOS `workerConcurrency` tier): correct for the common\n * single-orchestrator deployment. Global, cross-instance limits would need a durable counter in the\n * store — a deliberate follow-up, not built here.\n *\n * Beyond raw caps, the controller can admit contended slots by PRIORITY and by per-KEY FAIRNESS\n * (round-robin), so a single noisy key/tenant can't monopolize the concurrency budget. This is the\n * DISPATCH/admission layer — it never touches workflow replay (engine positional logic). Default\n * behaviour is unchanged FIFO when neither priority nor fairness is configured/passed.\n *\n * Design (vs Temporal/Inngest/DBOS): Temporal task queues are FIFO with separate priority levels;\n * Inngest concurrency keys + throttle give per-key fairness; DBOS queues are FIFO with a\n * `workerConcurrency` cap. We fold both knobs into the same in-process admission gate: an optional\n * per-call `priority` (higher first) and an optional queue-level `fairness: 'key'` (round-robin by\n * the per-call `key`). Because blocked calls re-suspend durably and retry independently (there is no\n * resident FIFO list to reorder), the controller remembers the set of WAITERS that asked-and-were-\n * blocked, and on a later retry only admits the one that is rightful-next under the policy.\n */\nexport interface QueueConfig {\n /** Queue name, referenced by `ctx.call(step, input, { queue: name })`. */\n name: string;\n /** Max steps in flight at once for this queue (this instance). Omit for unlimited. */\n concurrency?: number;\n /** Fixed-window rate limit: at most `limit` admissions per `periodMs`. Omit for unlimited. */\n rateLimit?: { limit: number; periodMs: number };\n /** Delay (ms) before a concurrency-blocked call re-checks for a free slot. Default 1000. */\n retryMs?: number;\n /**\n * Fairness policy for a contended concurrency slot. `'key'` round-robins across distinct per-call\n * keys (the least-recently-served key wins the next slot), so one key can't monopolize the budget.\n * Omit (or `'fifo'`) for plain first-come ordering. Priority always wins over fairness; fairness\n * only breaks ties within the same priority.\n */\n fairness?: 'fifo' | 'key';\n /**\n * Arrival-order tiebreak among otherwise-equal waiters (same priority, same fairness rank).\n * `'fifo'` (default) admits the earliest arrival; `'lifo'` admits the most recent (a stack). Orthogonal\n * to `priority` and `fairness` — those still win first; this only breaks their ties.\n */\n order?: 'fifo' | 'lifo';\n}\n\n/**\n * Per-call admission hints. All optional — omitting them keeps the legacy FIFO behaviour.\n * - `priority`: higher is admitted first (default 0).\n * - `key`: the fairness bucket (e.g. a tenant id) for `fairness: 'key'`.\n * - `waiterId`: a stable id for THIS call across its retries (the engine passes the stepId), so the\n * controller can track it as one waiter instead of counting each retry as a new contender.\n */\nexport interface AdmissionItem {\n priority?: number | undefined;\n key?: string | undefined;\n waiterId?: string | undefined;\n}\n\n/** Admission decision: either admitted, or blocked until `retryAt` (epoch ms). */\nexport type Admission = { ok: true } | { ok: false; retryAt: number };\n\n/** A call that asked for a slot and was blocked — remembered so the controller can order admission. */\ninterface Waiter {\n priority: number;\n key?: string | undefined;\n /** Monotonic registration order — FIFO tiebreak within equal priority/fairness. */\n seq: number;\n}\n\n/** In-process admission controller for one {@link QueueConfig}. */\nexport class QueueController {\n private inFlight = 0;\n private windowStart = 0;\n private windowCount = 0;\n /** Registered waiters by id (only used when priority/fairness ordering is in play). */\n private readonly waiters = new Map<string, Waiter>();\n /** Monotonic counter stamping each newly-seen waiter for a stable FIFO tiebreak. */\n private waiterSeq = 0;\n /** Per-key \"last served\" order for round-robin fairness — higher = more recently served. */\n private readonly keyServed = new Map<string, number>();\n private servedTick = 0;\n\n constructor(\n readonly config: QueueConfig,\n private readonly clock: () => number,\n ) {}\n\n /** Whether this controller does any priority/fairness ordering (else it's a plain FIFO gate). */\n private get ordered(): boolean {\n return this.config.fairness === 'key' || this.config.order === 'lifo';\n }\n\n /**\n * Try to admit one unit of work. On `ok`, the caller has taken a concurrency slot and must call\n * {@link release} when the step settles. On block, `retryAt` is when admission may next succeed.\n *\n * `item` carries optional priority/fairness hints; omitting it is the legacy FIFO path. When\n * ordering is configured (or a priority is given), a blocked call REGISTERS as a waiter and is only\n * admitted on a later retry once it is the rightful next under (priority desc, fairness, FIFO).\n */\n tryAdmit(item?: AdmissionItem): Admission {\n const now = this.clock();\n const rl = this.config.rateLimit;\n // Rate limit is a hard global window — checked first and unaffected by priority/fairness.\n if (rl) {\n if (now - this.windowStart >= rl.periodMs) {\n this.windowStart = now;\n this.windowCount = 0;\n }\n if (this.windowCount >= rl.limit)\n return { ok: false, retryAt: this.windowStart + rl.periodMs };\n }\n\n const usingOrder = this.ordered || item?.priority != null || item?.waiterId != null;\n const waiterId = item?.waiterId;\n\n // Concurrency gate.\n const full = this.config.concurrency != null && this.inFlight >= this.config.concurrency;\n if (full) {\n // No slot at all → block (and register as a waiter so a later retry can be ordered).\n if (usingOrder && waiterId != null) this.register(waiterId, item);\n return { ok: false, retryAt: now + (this.config.retryMs ?? 1000) };\n }\n\n // A slot is free. Without ordering, admit immediately (legacy FIFO). With ordering, only admit if\n // THIS call is the rightful next among all registered waiters — otherwise keep it waiting so the\n // freed slot can go to a higher-priority / under-served key on its retry.\n if (usingOrder && this.waiters.size > 0) {\n if (waiterId != null) this.register(waiterId, item);\n if (!this.isNext(waiterId, item)) {\n return { ok: false, retryAt: now + (this.config.retryMs ?? 1000) };\n }\n }\n\n // Admit: consume the slot, the rate-window tick, and clear this waiter.\n if (rl) this.windowCount += 1;\n this.inFlight += 1;\n if (waiterId != null) this.waiters.delete(waiterId);\n if (item?.key != null) this.keyServed.set(item.key, ++this.servedTick);\n return { ok: true };\n }\n\n /** Release a concurrency slot taken by a successful {@link tryAdmit}. */\n release(): void {\n if (this.inFlight > 0) this.inFlight -= 1;\n }\n\n /** Track (or refresh) a blocked call as a waiter; its FIFO seq is stamped only on first sight. */\n private register(waiterId: string, item?: AdmissionItem): void {\n const existing = this.waiters.get(waiterId);\n if (existing) {\n existing.priority = item?.priority ?? 0;\n existing.key = item?.key;\n return;\n }\n this.waiters.set(waiterId, {\n priority: item?.priority ?? 0,\n key: item?.key,\n seq: this.waiterSeq++,\n });\n }\n\n /**\n * Is the calling item the best candidate among all registered waiters? Ordering, best first:\n * 1. higher `priority`;\n * 2. fairness: with `fairness: 'key'`, the least-recently-served key wins (round-robin);\n * 3. earliest registration (FIFO) — stable tiebreak.\n * A bare item (no waiterId) is compared on its hints directly.\n */\n private isNext(waiterId: string | undefined, item?: AdmissionItem): boolean {\n const self: Waiter =\n (waiterId != null ? this.waiters.get(waiterId) : undefined) ??\n ({ priority: item?.priority ?? 0, key: item?.key, seq: Number.POSITIVE_INFINITY } as Waiter);\n let best = self;\n for (const w of this.waiters.values()) {\n if (this.better(w, best)) best = w;\n }\n return best === self;\n }\n\n /** Strict \"a should be admitted before b\" comparison under the active policy. */\n private better(a: Waiter, b: Waiter): boolean {\n if (a.priority !== b.priority) return a.priority > b.priority;\n if (this.config.fairness === 'key') {\n const sa = this.servedOf(a.key);\n const sb = this.servedOf(b.key);\n if (sa !== sb) return sa < sb; // least-recently-served key first\n }\n return this.config.order === 'lifo' ? a.seq > b.seq : a.seq < b.seq; // arrival tiebreak\n }\n\n /** Last-served tick for a key (0 = never served, so an unseen key is admitted before a busy one). */\n private servedOf(key?: string): number {\n if (key == null) return 0;\n return this.keyServed.get(key) ?? 0;\n }\n}\n","import { type Admission, type AdmissionItem, type QueueConfig, QueueController } from './queue';\n\n/**\n * Pluggable backend for the remote-step flow-control gate (`ctx.call(step, input, { queue })`). The\n * engine asks it whether a queued call may be admitted now (concurrency / rate / ordering) and tells\n * it when an admitted slot is released.\n *\n * The default {@link InMemoryAdmissionBackend} keeps per-instance counts — correct for a single\n * orchestrator. Swap in a store/Redis-backed backend to make the caps and ordering GLOBAL across\n * engine replicas (so `concurrency: 5` means 5 in-flight across the whole fleet, not 5 per pod).\n *\n * `tryAdmit`/`release` are async so a global backend can do its atomic round-trip; the in-memory one\n * resolves synchronously. An UNREGISTERED queue name is treated as ungated (admits immediately) — the\n * engine only tracks/releases a slot for a registered queue.\n */\nexport interface AdmissionBackend {\n /** Register (or replace) a queue's config. Called from `engine.registerQueue`. */\n register(config: QueueConfig): void;\n /** Whether `queue` is registered (gated). The engine only tracks/releases a slot for a gated queue. */\n handles(queue: string): boolean;\n /** May a call on `queue` take a slot now? On `ok`, the caller holds a slot until {@link release}. */\n tryAdmit(queue: string, item: AdmissionItem): Promise<Admission>;\n /**\n * Release the slot granted by {@link tryAdmit} for `queue`. `slotId` is the admitted item's\n * `waiterId` (the engine's stepId), so a lease-based backend can drop the exact slot; an in-process\n * counter ignores it.\n */\n release(queue: string, slotId: string): Promise<void>;\n /**\n * Optional: subscribe to \"a slot just freed on `queue`\" events (e.g. a fleet-wide pub/sub). The\n * engine uses it to wake its admission-blocked runs early instead of waiting for their retry tick.\n * A backend without it falls back to retry-tick polling. Fired best-effort across the fleet.\n */\n onFreed?(handler: (queue: string) => void): void;\n}\n\n/**\n * Default admission backend: one in-process {@link QueueController} per registered queue. Caps and\n * waiter ordering are per engine instance (see {@link QueueConfig}). Preserves the exact pre-backend\n * behaviour — the engine used to hold these controllers directly.\n */\nexport class InMemoryAdmissionBackend implements AdmissionBackend {\n private readonly controllers = new Map<string, QueueController>();\n\n constructor(private readonly clock: () => number) {}\n\n register(config: QueueConfig): void {\n this.controllers.set(config.name, new QueueController(config, this.clock));\n }\n\n handles(queue: string): boolean {\n return this.controllers.has(queue);\n }\n\n async tryAdmit(queue: string, item: AdmissionItem): Promise<Admission> {\n const controller = this.controllers.get(queue);\n // Unregistered queue → ungated (mirrors the old `this.queues.get(queue)` truthiness check).\n if (!controller) return { ok: true };\n return controller.tryAdmit(item);\n }\n\n async release(queue: string, _slotId: string): Promise<void> {\n this.controllers.get(queue)?.release();\n }\n}\n","const UNIT_MS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n sec: 1_000,\n second: 1_000,\n seconds: 1_000,\n m: 60_000,\n min: 60_000,\n minute: 60_000,\n minutes: 60_000,\n h: 3_600_000,\n hr: 3_600_000,\n hour: 3_600_000,\n hours: 3_600_000,\n d: 86_400_000,\n day: 86_400_000,\n days: 86_400_000,\n w: 604_800_000,\n week: 604_800_000,\n weeks: 604_800_000,\n};\n\n/**\n * Parse a human duration to milliseconds. Accepts a number (already ms) or a string like\n * `'500ms'`, `'30s'`, `'15m'`, `'2h'`, `'7d'`, `'7 days'`.\n */\nexport function parseDuration(duration: string | number): number {\n if (typeof duration === 'number') return duration;\n const match = duration.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*([a-z]+)$/i);\n if (!match) throw new Error(`invalid duration: ${duration}`);\n const value = Number(match[1]);\n const unit = (match[2] ?? '').toLowerCase();\n const factor = UNIT_MS[unit];\n if (factor === undefined) throw new Error(`unknown duration unit: ${unit}`);\n return value * factor;\n}\n","import type { StepOptions } from './interfaces';\n\n/** Delay in ms before the next retry attempt, per a step's `StepOptions` backoff config. Shared by\n * the local-step retry loop and the durable remote-step retry, so they stay consistent. */\nexport function backoffDelay(attempt: number, options?: StepOptions): number {\n const base = options?.backoffMs ?? 0;\n if (base <= 0) return 0;\n const raw = options?.backoff === 'exp' ? base * 2 ** (attempt - 1) : base;\n const capped = options?.backoffMaxMs ? Math.min(raw, options.backoffMaxMs) : raw;\n return options?.jitter ? Math.round(capped * (0.5 + Math.random() * 0.5)) : capped;\n}\n","import type { StepEvent, StepLogger, SubProcessHandle } from './interfaces';\n\n/** Attach the elapsed `durationMs` (from `start`) to `data`, unless the caller already set one. */\nfunction withDuration(start: number, now: () => number, data?: unknown): Record<string, unknown> {\n if (data && typeof data === 'object' && 'durationMs' in data) {\n return data as Record<string, unknown>;\n }\n const base = data && typeof data === 'object' ? (data as Record<string, unknown>) : {};\n return { ...base, durationMs: now() - start };\n}\n\n/**\n * A {@link StepLogger} that appends to `events`, stamping each line with `now()`. Shared by the\n * local-step path (`ctx.step`) and the remote-worker path (`runStepHandler`) so a step records\n * the same {@link StepEvent} shape wherever it runs — the TypeScript twin of the Python SDK's\n * `StepContext`.\n */\nexport function createStepLogger(events: StepEvent[], now: () => number): StepLogger {\n // The sub-process a `subProcess(...)` body is currently inside; debug/info/warn/error emitted while\n // inside get tagged with its id, so the dashboard groups that log trail under the sub-process.\n let currentSub: { id: string } | undefined;\n const push = (level: StepEvent['level'], message: string, data?: unknown) =>\n events.push({\n at: now(),\n level,\n message,\n ...(currentSub ? { subId: currentSub.id } : {}),\n ...(data === undefined ? {} : { data }),\n });\n const subEvent: StepLogger['subEvent'] = (e) =>\n events.push({\n at: now(),\n level: e.status === 'failed' ? 'error' : e.status === 'skipped' ? 'warn' : 'info',\n message: e.message ?? e.phase ?? e.name,\n subId: e.id,\n name: e.name,\n ...(e.group === undefined ? {} : { group: e.group }),\n ...(e.phase === undefined ? {} : { phase: e.phase }),\n ...(e.status === undefined ? {} : { status: e.status }),\n ...(e.data === undefined ? {} : { data: e.data }),\n });\n const subProcess: StepLogger['subProcess'] = async (name, body, opts) => {\n const id = opts?.id ?? globalThis.crypto.randomUUID();\n const group = opts?.group;\n const start = now();\n const prevSub = currentSub;\n currentSub = { id };\n let terminal = false;\n const emit = (status: 'ok' | 'failed' | 'skipped', message?: string, data?: unknown) => {\n if (terminal) return;\n terminal = true;\n subEvent({ id, name, group, status, message, data: withDuration(start, now, data) });\n };\n const handle: SubProcessHandle = {\n phase: (phase, data) => {\n if (!terminal) subEvent({ id, name, group, phase, data });\n return handle;\n },\n skip: (reason, data) => emit('skipped', reason, data),\n fail: (reason, data) => emit('failed', reason, data),\n };\n try {\n const result = await body(handle);\n emit('ok'); // no-op if the body already called skip()/fail()\n return result;\n } catch (err) {\n emit('failed', err instanceof Error ? err.message : String(err));\n throw err;\n } finally {\n currentSub = prevSub;\n }\n };\n return {\n debug: (m, d) => push('debug', m, d),\n info: (m, d) => push('info', m, d),\n warn: (m, d) => push('warn', m, d),\n error: (m, d) => push('error', m, d),\n sub: (name, status, message, data) =>\n events.push({\n at: now(),\n level: status === 'failed' ? 'error' : status === 'skipped' ? 'warn' : 'info',\n message: message ?? name,\n name,\n status,\n ...(data === undefined ? {} : { data }),\n }),\n subEvent,\n subProcess,\n };\n}\n","import type { RemoteTask, StepEvent, StepLogger, StepResult } from './interfaces';\nimport { createStepLogger } from './step-logger';\n\n/** Canonical step id — the stable identity of a step within a run, used for dedupe and\n * correlation. The format is part of the cross-language wire contract (Python builds the same). */\nexport function stepId(runId: string, seq: number): string {\n return `${runId}:${seq}`;\n}\n\n/** Deterministic signal token a breakpoint suspends on — derived from its logical position. Shared\n * so `ctx.breakpoint` (which records it) and `engine.continue` (which signals it) agree. */\nexport const breakpointToken = (runId: string, seq: number): string => `bp:${runId}:${seq}`;\n\n/** A remote-worker step body. The optional `log` records sub-process outcomes and debug/error\n * lines that ride back on the result — the TypeScript twin of the Python SDK's `StepContext`. */\nexport type StepHandler = (input: unknown, log: StepLogger) => Promise<unknown> | unknown;\n\n/**\n * Run `handler` for `task` and produce the wire-format {@link StepResult}. Pure (no transport,\n * no I/O beyond the handler), so every transport — and any language port — can share the exact\n * same completed / failed / no-handler contract instead of re-deriving it.\n */\nexport async function runStepHandler(\n task: RemoteTask,\n handler: StepHandler | undefined,\n): Promise<StepResult> {\n // Stamp the worker's pickup time so the engine can report queue-wait (startedAt − enqueuedAt).\n // This is the one place every transport funnels through, so timing comes for free everywhere.\n const base = { runId: task.runId, seq: task.seq, stepId: task.stepId, startedAt: Date.now() };\n if (!handler) {\n return {\n ...base,\n status: 'failed',\n error: { message: `no handler for ${task.name}`, retryable: false },\n };\n }\n const events: StepEvent[] = [];\n const withEvents = (result: StepResult): StepResult =>\n events.length > 0 ? { ...result, events } : result;\n try {\n const output = await handler(task.input, createStepLogger(events, Date.now));\n return withEvents({ ...base, status: 'completed', output });\n } catch (err) {\n // Carry `code`/`retryable` off the thrown error if present, so the engine's durable retry can\n // honour a worker's \"don't retry this\" verdict (e.g. a declined card).\n const e = err as { message?: string; code?: string; retryable?: boolean };\n return withEvents({\n ...base,\n status: 'failed',\n error: {\n message: err instanceof Error ? err.message : String(err),\n ...(typeof e?.code === 'string' ? { code: e.code } : {}),\n ...(typeof e?.retryable === 'boolean' ? { retryable: e.retryable } : {}),\n },\n });\n }\n}\n","import type { StepCheckpoint, StepError, StepEvent, StepKind } from './interfaces';\nimport { stepId } from './protocol';\n\n/** Drop an empty events array to `undefined` (the repeated `events?.length ? events : undefined`). */\nfunction nonEmptyEvents(events: StepEvent[] | undefined): StepEvent[] | undefined {\n return events && events.length > 0 ? events : undefined;\n}\n\n/**\n * Build a *phased* step checkpoint — one with distinct enqueue/run/finish timestamps (a local step\n * that is running/completed/failed, or a pending remote/sleep step). Computes the deterministic\n * `stepId` and normalizes empty event arrays, so the engine's running/completed/failed/pending\n * checkpoint literals are constructed in exactly one place instead of ~8.\n *\n * For instantaneous checkpoints (sleep timers, markers, delivered signals) use {@link instantCheckpoint}.\n */\nexport function stepCheckpoint(p: {\n runId: string;\n seq: number;\n name: string;\n kind: StepKind;\n status: StepCheckpoint['status'];\n attempts: number;\n enqueuedAt: Date;\n startedAt: Date;\n finishedAt: Date;\n input?: unknown;\n output?: unknown;\n error?: StepError | undefined;\n events?: StepEvent[] | undefined;\n workerGroup?: string | undefined;\n wakeAt?: number | undefined;\n}): StepCheckpoint {\n return {\n runId: p.runId,\n seq: p.seq,\n name: p.name,\n kind: p.kind,\n stepId: stepId(p.runId, p.seq),\n status: p.status,\n input: p.input,\n output: p.output,\n error: p.error,\n events: nonEmptyEvents(p.events),\n attempts: p.attempts,\n workerGroup: p.workerGroup,\n wakeAt: p.wakeAt,\n enqueuedAt: p.enqueuedAt,\n startedAt: p.startedAt,\n finishedAt: p.finishedAt,\n };\n}\n\n/**\n * Build an *instantaneous* checkpoint — one with no distinct enqueue/run/finish phases (a durable\n * sleep timer, a breakpoint marker, a delivered signal, a published `setEvent` value, a `patched`\n * marker). All three timestamps collapse to now and `attempts` is 1. Collapses what was five\n * near-identical 10-field `saveCheckpoint({...})` literals into one builder.\n */\nexport function instantCheckpoint(p: {\n runId: string;\n seq: number;\n name: string;\n kind: StepKind;\n status?: StepCheckpoint['status'];\n output?: unknown;\n wakeAt?: number;\n}): StepCheckpoint {\n const at = new Date();\n return {\n runId: p.runId,\n seq: p.seq,\n name: p.name,\n kind: p.kind,\n stepId: stepId(p.runId, p.seq),\n status: p.status ?? 'completed',\n output: p.output,\n wakeAt: p.wakeAt,\n attempts: 1,\n enqueuedAt: at,\n startedAt: at,\n finishedAt: at,\n };\n}\n","/**\n * Thrown inside a step to signal an unrecoverable failure: the engine will NOT retry it,\n * regardless of the step's `retries` setting, and fails the run immediately. Use it for\n * business errors that retrying cannot fix (e.g. a declined card, invalid input).\n */\nexport class FatalError extends Error {\n readonly code?: string | undefined;\n constructor(message: string, code?: string) {\n super(message);\n this.name = 'FatalError';\n this.code = code;\n }\n}\n\n/**\n * Thrown by `start` when a singleton workflow's wait queue is full: the count of in-flight + gated\n * runs sharing the key already equals `limit + maxQueueDepth`, so admitting another would let the\n * same-key backlog grow unbounded. Back-pressure — the caller should retry later or shed load. Only\n * raised when {@link SingletonConfig.maxQueueDepth} is set (omit it for the old unbounded behavior).\n */\nexport class SingletonQueueFullError extends Error {\n readonly workflow: string;\n readonly key: string;\n readonly maxQueueDepth: number;\n constructor(workflow: string, key: string, maxQueueDepth: number) {\n super(\n `singleton queue for ${workflow} key \"${key}\" is full (maxQueueDepth=${maxQueueDepth}); retry later`,\n );\n this.name = 'SingletonQueueFullError';\n this.workflow = workflow;\n this.key = key;\n this.maxQueueDepth = maxQueueDepth;\n }\n}\n\n/**\n * Internal control signal thrown to suspend a run (e.g. on a durable sleep). Not an error the\n * user should throw or catch; the engine uses it to stop execution and persist `wakeAt`.\n */\nexport class SignalTimeoutError extends Error {\n readonly token: string;\n readonly timeoutMs: number;\n constructor(token: string, timeoutMs: number) {\n super(`timed out after ${timeoutMs}ms waiting for signal \"${token}\"`);\n this.name = 'SignalTimeoutError';\n this.token = token;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Thrown when a remote step produces no result and no heartbeat within its `timeoutMs` window —\n * i.e. the worker is presumed dead. Subject to the step's `retries` (it's retryable), so the engine\n * re-dispatches before giving up.\n */\nexport class RemoteStepTimeout extends Error {\n readonly stepId: string;\n readonly timeoutMs: number;\n constructor(stepId: string, timeoutMs: number) {\n super(`remote step ${stepId} produced no result/heartbeat within ${timeoutMs}ms`);\n this.name = 'RemoteStepTimeout';\n this.stepId = stepId;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Thrown on resume when the workflow code no longer matches the recorded history: the step at a\n * logical position has a different name/kind than the checkpoint saved there. This means the\n * workflow definition changed (a step was added/removed/reordered) under an in-flight run without a\n * new `@Workflow` version — continuing would replay the wrong checkpoint into the wrong step and\n * silently corrupt the run, so the engine fails loudly instead. Register a new workflow version for\n * breaking changes (old runs finish on the version they started on).\n */\nexport class NonDeterminismError extends Error {\n readonly runId: string;\n readonly seq: number;\n constructor(runId: string, seq: number, expected: string, recorded: string) {\n super(\n `non-determinism at ${runId}#${seq}: code expects \"${expected}\" but history recorded ` +\n `\"${recorded}\". The workflow changed under an in-flight run — register a new @Workflow version.`,\n );\n this.name = 'NonDeterminismError';\n this.runId = runId;\n this.seq = seq;\n }\n}\n\nexport class WorkflowSuspended extends Error {\n /** Epoch ms to auto-resume (durable sleep), or undefined when waiting on an external signal. */\n readonly wakeAt?: number | undefined;\n constructor(wakeAt?: number) {\n super('workflow suspended');\n this.name = 'WorkflowSuspended';\n this.wakeAt = wakeAt;\n }\n}\n\n/**\n * Thrown by `ctx.continueAsNew(input)` to end the current run and hand off to a fresh execution of\n * the same workflow with a clean history — for long-running / looping workflows that would otherwise\n * accumulate unbounded checkpoints. The engine completes this run and starts the next one.\n */\nexport class ContinueAsNew extends Error {\n constructor(readonly input: unknown) {\n super('workflow continued as new');\n this.name = 'ContinueAsNew';\n }\n}\n","import { FatalError } from './errors';\nimport type { WorkflowCtx } from './interfaces';\n\n/** One operation on a durable entity: mutate `state` in place and/or return a result. */\nexport type EntityHandler<S = unknown> = (state: S, arg: unknown) => unknown | Promise<unknown>;\n\n/** A durable keyed entity (a virtual object): per-key serialized handlers over durable state. */\nexport interface EntityConfig<S = unknown> {\n /** Build the initial state for a fresh key. */\n initialState: () => S;\n /** Operation handlers, keyed by op name. Each runs serially per key, exactly once. */\n handlers: Record<string, EntityHandler<S>>;\n}\n\n/** The slice of the engine the entity subsystem needs (so it stays a standalone module). */\nexport interface EntityHost {\n register(\n name: string,\n version: string,\n fn: (ctx: WorkflowCtx, input: unknown) => Promise<unknown>,\n ): void;\n signalWithStart(\n workflow: string,\n input: unknown,\n runId: string,\n signal: { token: string; payload?: unknown },\n ): Promise<{ runId: string }>;\n getEvent<T>(runId: string, key: string): Promise<T | undefined>;\n signal(token: string, payload: unknown): Promise<unknown>;\n}\n\nconst ENTITY_WORKFLOW = '__entity';\nconst entityRunId = (name: string, key: string): string => `entity:${name}:${key}`;\n\n/**\n * Durable keyed **entities** (virtual objects): a keyed actor whose handlers run **serialized per\n * key** over **durable state**, exactly once. Each key is one long-lived run (`entity:<name>:<key>`)\n * processing ops in order. Drive it with `signal` (fire) or `ctx.callEntity` (call + await result),\n * read state with `getState`. Registers its built-in runner on construction.\n */\nexport class Entities {\n private readonly configs = new Map<string, EntityConfig>();\n\n constructor(private readonly host: EntityHost) {\n host.register(ENTITY_WORKFLOW, '1', (ctx, input) => this.run(ctx, input));\n }\n\n register<S>(name: string, config: EntityConfig<S>): void {\n this.configs.set(name, config as EntityConfig);\n }\n\n /** Deliver an op to an entity's runner, starting it on first contact. `reply` (a signal token)\n * receives the handler's result, for `ctx.callEntity`. */\n dispatch(\n name: string,\n key: string,\n op: string,\n arg: unknown,\n reply?: string,\n ): Promise<{ runId: string }> {\n const runId = entityRunId(name, key);\n return this.host.signalWithStart(ENTITY_WORKFLOW, { name, key }, runId, {\n token: runId,\n payload: { op, arg, reply },\n });\n }\n\n async signal(name: string, key: string, op: string, arg?: unknown): Promise<void> {\n await this.dispatch(name, key, op, arg);\n }\n\n getState<S = unknown>(name: string, key: string): Promise<S | undefined> {\n return this.host.getEvent<S>(entityRunId(name, key), 'state');\n }\n\n /** The built-in runner: one long-lived run per key, processing ops serially over state. */\n private async run(ctx: WorkflowCtx, input: unknown): Promise<unknown> {\n const { name, key } = input as { name: string; key: string };\n const config = this.configs.get(name);\n if (!config) throw new FatalError(`entity \"${name}\" is not registered`);\n const token = entityRunId(name, key);\n let state = config.initialState();\n for (let i = 0; ; i += 1) {\n const msg = (await ctx.waitForSignal(token)) as { op: string; arg: unknown; reply?: string };\n // Run the handler and snapshot the (possibly mutated) state in ONE checkpoint, so replay\n // restores the state from the checkpoint instead of re-running the handler.\n const out = await ctx.step(`op:${i}`, async () => {\n const handler = config.handlers[msg.op];\n if (!handler) throw new FatalError(`entity \"${name}\" has no handler for op \"${msg.op}\"`);\n const result = await handler(state, msg.arg);\n return { result, state };\n });\n state = out.state; // carry state forward (and restore it from the checkpoint on replay)\n await ctx.setEvent('state', state); // publish for getState\n if (msg.reply) {\n await ctx.step(`reply:${i}`, async () => {\n await this.host.signal((msg as { reply: string }).reply, out.result);\n });\n }\n }\n }\n}\n","import { SignalTimeoutError } from './errors';\nimport type { WorkflowCtx } from './interfaces';\n\n/** How `onEvent` triggers are coalesced into fewer runs (see `@Workflow({ debounce | batch })`). */\nexport type EventBatchConfig =\n | { mode: 'debounce'; windowMs: number }\n | { mode: 'batch'; maxSize: number; windowMs: number };\n\n/** The slice of the engine the accumulators need (so they stay a standalone module). */\nexport interface AccumulatorHost {\n register(\n name: string,\n version: string,\n fn: (ctx: WorkflowCtx, input: unknown) => Promise<unknown>,\n ): void;\n signalWithStart(\n workflow: string,\n input: unknown,\n runId: string,\n signal: { token: string; payload?: unknown },\n ): Promise<{ runId: string }>;\n}\n\nconst accToken = (target: string): string => `__evtacc__:${target}`;\n\n/**\n * Built-in workflows that coalesce `onEvent` triggers. Each is a long-lived per-target accumulator\n * fed by `signalWithStart`: it collects payloads then starts the target once, and `continueAsNew`s to\n * re-arm for the next burst. Signal buffering keeps the re-arm race-free. Registers its runners on\n * construction.\n */\nexport class EventAccumulators {\n constructor(private readonly host: AccumulatorHost) {\n host.register('__evt_debounce', '1', (ctx, input) => this.debounce(ctx, input));\n host.register('__evt_batch', '1', (ctx, input) => this.batch(ctx, input));\n }\n\n /** Route an `onEvent` payload into its target's debounce/batch accumulator. */\n route(target: string, config: EventBatchConfig, payload: unknown): Promise<{ runId: string }> {\n const [workflow, input] =\n config.mode === 'debounce'\n ? (['__evt_debounce', { target, windowMs: config.windowMs }] as const)\n : ([\n '__evt_batch',\n { target, maxSize: config.maxSize, windowMs: config.windowMs },\n ] as const);\n return this.host.signalWithStart(workflow, input, accToken(target), {\n token: accToken(target),\n payload,\n });\n }\n\n /** Fire the target with the LAST payload once events have been quiet for `windowMs`. */\n private async debounce(ctx: WorkflowCtx, input: unknown): Promise<unknown> {\n const { target, windowMs } = input as { target: string; windowMs: number };\n const token = accToken(target);\n let last = await ctx.waitForSignal(token); // park for the first event of a burst\n for (;;) {\n try {\n last = await ctx.waitForSignal(token, { timeoutMs: windowMs }); // extend on each event\n } catch (e) {\n if (e instanceof SignalTimeoutError) break; // quiet for `windowMs` → fire\n throw e; // WorkflowSuspended / ContinueAsNew etc. must propagate\n }\n }\n await ctx.startChild(target, last);\n return ctx.continueAsNew(input); // re-arm\n }\n\n /** Fire the target with all payloads (`{ events }`) once `maxSize` or `windowMs` from the first. */\n private async batch(ctx: WorkflowCtx, input: unknown): Promise<unknown> {\n const { target, maxSize, windowMs } = input as {\n target: string;\n maxSize: number;\n windowMs: number;\n };\n const token = accToken(target);\n const events: unknown[] = [await ctx.waitForSignal(token)]; // park for the first\n const deadline = (await ctx.now()) + windowMs;\n while (events.length < maxSize) {\n const remaining = deadline - (await ctx.now());\n if (remaining <= 0) break;\n try {\n events.push(await ctx.waitForSignal(token, { timeoutMs: remaining }));\n } catch (e) {\n if (e instanceof SignalTimeoutError) break; // window elapsed → fire what we have\n throw e; // WorkflowSuspended / ContinueAsNew etc. must propagate\n }\n }\n await ctx.startChild(target, { events });\n return ctx.continueAsNew(input); // re-arm\n }\n}\n","// Named events: pub/sub on top of the signal-waiter table. A `ctx.waitForEvent(name, { match })`\n// registers a signal waiter whose token encodes the event name + match criteria (base64 so they\n// never contain the `:` delimiter); `engine.publishEvent(name, payload)` lists the waiters for that\n// name by token prefix, checks each one's match against the payload, and signals the ones that pass.\n// No schema change beyond a `listSignalWaiters(prefix)` store method.\n\nconst enc = (s: string): string => Buffer.from(s, 'utf8').toString('base64');\nconst dec = (s: string): string => Buffer.from(s, 'base64').toString('utf8');\n\n/** Token prefix for every waiter on `name` — used by `listSignalWaiters` to fan an event out. */\nexport function eventPrefix(name: string): string {\n return `event:${enc(name)}:`;\n}\n\n/** Build the unique waiter token for one `waitForEvent` call (name + match + run position). */\nexport function eventToken(\n name: string,\n match: Record<string, unknown> | undefined,\n runId: string,\n seq: number,\n): string {\n return `${eventPrefix(name)}${enc(JSON.stringify(match ?? {}))}:${runId}#${seq}`;\n}\n\n/** The match criteria embedded in an event waiter token (the 3rd `:`-segment is the base64 match). */\nexport function eventMatchOf(token: string): Record<string, unknown> {\n try {\n return JSON.parse(dec(token.split(':')[2] ?? '')) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\n/** Whether `payload` satisfies a waiter's `match`: every match key deep-equals the payload's value. */\nexport function eventMatches(payload: unknown, match: Record<string, unknown>): boolean {\n const keys = Object.keys(match);\n if (keys.length === 0) return true; // no criteria → matches any payload of this name\n if (!payload || typeof payload !== 'object') return false;\n const p = payload as Record<string, unknown>;\n return keys.every((k) => JSON.stringify(p[k]) === JSON.stringify(match[k]));\n}\n","import type { SingletonConfig } from './engine';\nimport { SingletonQueueFullError } from './errors';\nimport type { StateStore, WorkflowRun } from './interfaces';\n\nconst SINGLETON_RETRY_MS = 1000;\n/**\n * Max jitter (ms, each direction) added to {@link SINGLETON_RETRY_MS} so a queue of N gated runs\n * doesn't wake in lockstep and stampede the admission scan. Each retry picks an independent offset\n * in `[-SINGLETON_RETRY_JITTER_MS, +SINGLETON_RETRY_JITTER_MS]`.\n */\nconst SINGLETON_RETRY_JITTER_MS = 250;\n\nexport interface SingletonGateDeps {\n store: Pick<StateStore, 'listRuns' | 'updateRun'>;\n clock: () => number;\n /** Hand a gated run to the run dispatcher (fire-and-forget, like the engine's other dispatches). */\n dispatch: (runId: string) => void;\n /** Resolve a settled run's singleton config from the engine's workflow registry. */\n configFor: (run: WorkflowRun) => SingletonConfig | undefined;\n}\n\n/**\n * Per-key serialization for singleton workflows — start-time back-pressure, FIFO race-free\n * admission, and notify-on-release wakeups. Extracted from {@link WorkflowEngine} so the whole\n * singleton feature lives in one place instead of being smeared across `start`, `execute`, both run\n * loops, and `cancel`.\n */\nexport class SingletonGate {\n constructor(private readonly deps: SingletonGateDeps) {}\n\n /** The tag a singleton run carries, so the gate can find others sharing its key. */\n tag(cfg: SingletonConfig, input: unknown): string {\n return `singleton:${cfg.key(input)}`;\n }\n\n /** Next wake time for a gated run: the base retry delay jittered to avoid a wakeup stampede. */\n retryWakeAt(): number {\n return (\n this.deps.clock() +\n SINGLETON_RETRY_MS +\n Math.floor((Math.random() * 2 - 1) * SINGLETON_RETRY_JITTER_MS)\n );\n }\n\n /**\n * Reject a start that would grow the same-key backlog past `limit + maxQueueDepth` (counting\n * `pending`/`running`/`suspended` runs sharing the key in one scan). No-op when no `maxQueueDepth`\n * is configured.\n */\n async assertCapacity(workflow: string, cfg: SingletonConfig, input: unknown): Promise<void> {\n if (cfg.maxQueueDepth == null) return;\n const cap = (cfg.limit ?? 1) + cfg.maxQueueDepth;\n const queued = await this.deps.store.listRuns({\n tag: this.tag(cfg, input),\n workflow,\n statuses: ['pending', 'running', 'suspended'],\n });\n if (queued.length >= cap) {\n throw new SingletonQueueFullError(workflow, cfg.key(input), cfg.maxQueueDepth);\n }\n }\n\n /**\n * Whether `run` may run now under its key: it's among the `limit` oldest in-flight (running or\n * suspended) runs sharing the key, by `(createdAt, id)` order. A consistent store gives every\n * instance the same ordering, so admission is race-free + FIFO.\n */\n async admit(run: WorkflowRun, cfg: SingletonConfig): Promise<boolean> {\n // ONE scan for both in-flight statuses; the total `(createdAt, id)` sort makes admission order\n // independent of the store's row order, preserving the FIFO + race-free-across-instances contract.\n const inflight = (\n await this.deps.store.listRuns({\n tag: this.tag(cfg, run.input),\n workflow: run.workflow,\n statuses: ['running', 'suspended'],\n })\n ).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime() || a.id.localeCompare(b.id));\n const idx = inflight.findIndex((r) => r.id === run.id);\n return idx >= 0 && idx < (cfg.limit ?? 1);\n }\n\n /**\n * Notify-on-release: a singleton run settled (freeing a slot), so dispatch the oldest gated\n * (`suspended` + same tag) waiters now instead of waiting for their ~1s retry timer. Each re-checks\n * admission in the executor and runs only if it actually wins a slot, so FIFO/race-free guarantees\n * hold; the durable timer remains the cross-instance/crash fallback.\n */\n async wakeNext(settled: WorkflowRun): Promise<void> {\n const cfg = this.deps.configFor(settled);\n if (!cfg) return;\n const tag = settled.tags?.find((t) => t.startsWith('singleton:'));\n if (!tag) return;\n const gated = (\n await this.deps.store.listRuns({ tag, workflow: settled.workflow, statuses: ['suspended'] })\n ).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime() || a.id.localeCompare(b.id));\n for (const next of gated.slice(0, cfg.limit ?? 1)) {\n // Clear the durable retry timer as we hand the run over, so the timer poller can't also pick it\n // up and double-dispatch. Only for runs that carry a wakeAt; dispatch after the clear commits.\n if (next.wakeAt != null) {\n await this.deps.store\n .updateRun(next.id, { wakeAt: undefined, updatedAt: new Date() })\n .catch(() => undefined);\n }\n this.deps.dispatch(next.id);\n }\n }\n}\n","import type {\n GroupHealth,\n Heartbeat,\n NamedTransport,\n RemoteTask,\n StepResult,\n WorkflowStepEvent,\n} from './interfaces';\n\n/**\n * An ordered pool of named transports. The engine dispatches on the first and fails over to the\n * next on a dispatch error; a step can pin one by id. Pure transport plumbing — no run lifecycle —\n * so it lives apart from the engine.\n */\nexport class TransportPool {\n constructor(private readonly transports: NamedTransport[]) {}\n\n get size(): number {\n return this.transports.length;\n }\n\n /** Register the engine's result/heartbeat/step-event handlers on EVERY transport — a result can come\n * back on whichever one delivered the task, so failover stays symmetric. `onStepEvent` is wired only\n * on transports that carry streamed workflow step lifecycle (BullMQ); others simply skip it. */\n bind(\n onResult: (result: StepResult) => Promise<void>,\n onHeartbeat: (beat: Heartbeat) => Promise<void>,\n onStepEvent?: (event: WorkflowStepEvent) => Promise<void>,\n ): void {\n for (const { transport } of this.transports) {\n transport.onResult(onResult);\n transport.onHeartbeat(onHeartbeat);\n if (onStepEvent && transport.onStepEvent) {\n transport.onStepEvent(onStepEvent);\n }\n }\n }\n\n /**\n * Dispatch `task` over the pool: try the preferred (or first) transport, fail over to the next on\n * a dispatch error, and stamp the task with the id of the transport that accepted it (so a worker\n * replies on the matching one). Throws if every transport fails.\n */\n async dispatch(task: Omit<RemoteTask, 'transport'>, preferId?: string): Promise<void> {\n let lastErr: unknown;\n for (const { id, transport } of this.ordered(preferId)) {\n try {\n await transport.dispatch({ ...task, transport: id });\n return;\n } catch (err) {\n lastErr = err;\n }\n }\n throw lastErr ?? new Error('no transport accepted the dispatch');\n }\n\n /** Worker-health for `group`, merged across every transport that can report it (a group's queue\n * and its workers may live on any pinned transport). Undefined when no transport implements\n * `groupHealth` (e.g. a pure in-process transport — nothing to introspect). */\n async groupHealth(group: string): Promise<GroupHealth | undefined> {\n const reports: GroupHealth[] = [];\n for (const { transport } of this.transports) {\n if (transport.groupHealth) reports.push(await transport.groupHealth(group));\n }\n if (reports.length === 0) return undefined;\n return {\n group,\n depth: reports.reduce((sum, r) => sum + r.depth, 0),\n liveWorkers: reports.flatMap((r) => r.liveWorkers),\n };\n }\n\n /** Distinct worker groups with a live heartbeat, merged across every transport that can report it. */\n async listWorkerGroups(): Promise<string[]> {\n const groups = new Set<string>();\n for (const { transport } of this.transports) {\n if (transport.listWorkerGroups) {\n for (const g of await transport.listWorkerGroups()) groups.add(g);\n }\n }\n return [...groups];\n }\n\n /** Pinned `preferId` first, then the rest (failover order). */\n private ordered(preferId?: string): NamedTransport[] {\n if (!preferId) return this.transports;\n const pref = this.transports.filter((t) => t.id === preferId);\n if (pref.length === 0) throw new Error(`transport \"${preferId}\" is not registered`);\n return [...pref, ...this.transports.filter((t) => t.id !== preferId)];\n }\n}\n","import { FatalError } from './errors';\n\n/**\n * The payload an external `ctx.task` / child run delivers back on its completion signal: either a\n * value or a failure. One typed envelope so `task` and `child` share the same unwrap (instead of\n * sniffing ad-hoc `__error` keys).\n */\nexport type Completion<T> = { ok: true; value: T } | { ok: false; error: string };\n\n/** Read a `Completion` from a signal payload: return the value, or throw a FatalError if it failed. */\nexport function unwrapCompletion<T>(payload: unknown, label: string): T {\n const c = payload as Completion<T> | null;\n if (c && typeof c === 'object' && 'ok' in c && c.ok === false) {\n throw new FatalError(`${label} failed: ${c.error}`);\n }\n return (c as { value: T } | null)?.value as T;\n}\n","/**\n * A **workflow reference** is how one workflow names another to call it: either a registered workflow\n * **name** (a string — the only option across runtimes, e.g. a Python workflow) or, for a same-runtime\n * TypeScript workflow, its **class**. The class carries the input/output types through the call, so\n * `ctx.child(ShippingWorkflow, input)` type-checks the input and returns a typed result — while a\n * string stays available for the cross-runtime case.\n */\n\n/**\n * The symbol the `@Workflow` decorator stamps a workflow's registered name onto, so a class ref can\n * be resolved back to its name. A global-registry symbol (`Symbol.for`) so it survives duplicate\n * copies of this package in a dependency tree.\n */\nexport const WORKFLOW_NAME_KEY: unique symbol = Symbol.for('nestjs-durable:workflow-name');\n\n/** Structural shape of a `@Workflow` class — its `run(ctx, input)` carries the input/output types. */\nexport type WorkflowClass<TInput = unknown, TOutput = unknown> = abstract new (\n ...args: never[]\n) => {\n run(ctx: never, input: TInput): Promise<TOutput> | TOutput;\n};\n\n/** A workflow reference: a registered name (cross-runtime) or a workflow class (typed, same-runtime). */\nexport type WorkflowRef<TInput = unknown, TOutput = unknown> =\n | string\n | WorkflowClass<TInput, TOutput>;\n\n/** The input type a workflow class's `run` accepts. */\nexport type WorkflowInputOf<C> = C extends abstract new (\n ...args: never[]\n) => {\n run(ctx: never, input: infer I): unknown;\n}\n ? I\n : unknown;\n\n/** The output type a workflow class's `run` resolves to (Promise unwrapped). */\nexport type WorkflowOutputOf<C> = C extends abstract new (\n ...args: never[]\n) => {\n run(ctx: never, input: never): infer R;\n}\n ? Awaited<R>\n : unknown;\n\n/**\n * Resolve a {@link WorkflowRef} to its registered workflow name: a string is returned as-is; a\n * `@Workflow` class is resolved via the name the decorator stamped on it. Throws if a class was\n * never decorated (so it carries no registered name).\n */\nexport function workflowName(ref: WorkflowRef): string {\n if (typeof ref === 'string') return ref;\n const name = (ref as { [WORKFLOW_NAME_KEY]?: string })[WORKFLOW_NAME_KEY];\n if (!name) {\n throw new Error(\n `workflow class ${ref.name} has no registered name — is it decorated with @Workflow({ name })?`,\n );\n }\n return name;\n}\n","import { backoffDelay } from './backoff';\nimport { instantCheckpoint } from './checkpoints';\nimport { unwrapCompletion } from './completion';\nimport { parseDuration } from './duration';\nimport {\n ContinueAsNew,\n FatalError,\n NonDeterminismError,\n SignalTimeoutError,\n WorkflowSuspended,\n} from './errors';\nimport { eventToken } from './events';\nimport type {\n ChildCallOptions,\n DurableWebhook,\n RemoteStepDef,\n StateStore,\n StepCheckpoint,\n StepError,\n StepEvent,\n StepInvocation,\n StepKind,\n StepLogger,\n StepOptions,\n WorkflowCtx,\n} from './interfaces';\nimport { breakpointToken } from './protocol';\nimport { createStepLogger } from './step-logger';\nimport { type WorkflowRef, workflowName } from './workflow-ref';\n\n/** Normalize the `ctx.child`/`ctx.startChild` 3rd arg: a bare string is shorthand for `{ childId }`. */\nfunction normalizeChildOptions(options?: string | ChildCallOptions): ChildCallOptions {\n return typeof options === 'string' ? { childId: options } : (options ?? {});\n}\n\n/** A saga undo registered by a completed step, kept with its step name for visibility on failure. */\nexport interface Compensation {\n name: string;\n fn: () => Promise<void>;\n}\n\n/** A finished local step the host should checkpoint and announce (completed or failed). */\nexport interface StepRecord {\n runId: string;\n seq: number;\n name: string;\n kind: StepKind;\n input?: unknown;\n events?: StepEvent[] | undefined;\n attempts: number;\n enqueuedAt: Date;\n startedAt: Date;\n workerGroup?: string | undefined;\n}\n\n/**\n * The narrow surface {@link createWorkflowCtx} needs from the engine — the seam between the\n * authoring API (this module) and the orchestrator (the engine owns lifecycle: emitting events,\n * suspending/resuming runs, dispatching remote steps).\n */\nexport interface CtxHost {\n readonly store: StateStore;\n /**\n * Per-execution checkpoint snapshot, loaded ONCE at execution start (the completed prefix this\n * replay walks). Lets each primitive read the prefix from memory instead of a per-call DB SELECT\n * (the O(N²) replay-reads fix). A seq ABSENT from the map is NOT cached — the primitive falls back\n * to the live store, so the checkpoint this resume is waking on (signal/timer/child, written after\n * the snapshot) is always read fresh. New checkpoints written during this execution are inserted\n * into the map so any later same-execution read sees them. Undefined ⇒ always hit the store.\n */\n readonly replay?: Map<number, StepCheckpoint> | undefined;\n clock(): number;\n webhookUrl?: ((token: string) => string) | undefined;\n /** Mark a local step's body as started — emits `step.started` and (optionally) a `running` checkpoint. */\n startStep(step: StepRecord): Promise<void>;\n completeStep(step: StepRecord & { output: unknown }): Promise<void>;\n failStep(step: StepRecord & { error: StepError }): Promise<void>;\n callRemote<TInput, TOutput>(\n runId: string,\n seq: number,\n step: RemoteStepDef<TInput, TOutput>,\n input: TInput,\n queue?: string,\n transport?: string,\n admission?: { priority?: number | undefined; fairnessKey?: string | undefined },\n ): Promise<TOutput>;\n /** Start a child run once, deferred so it can't reentrantly resume a still-running parent. */\n startChild(workflow: string, input: unknown, id: string, priority?: number): void;\n /** Deliver an op to a durable entity (deferred), optionally with a `reply` token for the result. */\n signalEntity?(name: string, key: string, op: string, arg: unknown, reply?: string): void;\n /** Run a local step body through the registered step interceptors (identity if none). */\n interceptStep?<T>(invocation: StepInvocation, body: () => Promise<T>): Promise<T>;\n}\n\n/** The per-run logical position counter. `rewind()` gives a position back (see `ctx.patched`). */\nclass Position {\n private seq = -1;\n next(): number {\n this.seq += 1;\n return this.seq;\n }\n rewind(): void {\n this.seq -= 1;\n }\n}\n\n/**\n * Build the {@link WorkflowCtx} handed to a workflow body. Every primitive is a closure over the\n * position counter (the per-run logical position) and the saga `compensations` stack, so `task`/\n * `child` compose `step`/`waitForSignal` directly. All durability goes through {@link CtxHost}, so\n * the workflow body stays deterministic.\n */\nexport function createWorkflowCtx(\n host: CtxHost,\n runId: string,\n compensations: Compensation[],\n workflow = '',\n): WorkflowCtx {\n const { store, replay } = host;\n const pos = new Position();\n\n // Read the checkpoint at `seq`: from the per-execution snapshot when present (no DB round-trip),\n // otherwise from the live store. Absence in the snapshot means \"written after the snapshot\" (the\n // signal/timer/child this resume wakes on, or nothing yet) — those MUST hit the store. Identical\n // behaviour to a raw `store.getCheckpoint`, just memoized for the completed prefix.\n const readCheckpoint = (seq: number): Promise<StepCheckpoint | null> | StepCheckpoint => {\n const hit = replay?.get(seq);\n if (hit !== undefined) return hit;\n return store.getCheckpoint(runId, seq);\n };\n\n // Persist a checkpoint AND reflect it in the snapshot, so a later same-execution read of this seq\n // (e.g. a re-read within the same call) sees it instead of falling back to the store.\n const writeCheckpoint = async (cp: StepCheckpoint): Promise<void> => {\n await store.saveCheckpoint(cp);\n replay?.set(cp.seq, cp);\n };\n\n const step = async <T>(\n name: string,\n fn: (log: StepLogger) => Promise<T>,\n options?: StepOptions,\n ): Promise<T> => {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.name !== name) {\n throw new NonDeterminismError(runId, current, name, existing.name);\n }\n if (existing && existing.status === 'completed') {\n // Register the compensation on replay too, so a saga undoes ALL completed steps — even\n // those done in an earlier (since-suspended) pass — not just the ones run this pass.\n if (options?.compensate) compensations.push({ name, fn: options.compensate });\n return existing.output as T;\n }\n const maxAttempts = Math.max(1, options?.retries ?? 1);\n const startedAt = new Date();\n // Announce the body has begun (and, when enabled, checkpoint it `running`) so the step is\n // visible in flight — not only once it settles. Skipped on replay: a completed step returns\n // above before reaching here, so this fires once, when the body actually first runs.\n await host.startStep({\n runId,\n seq: current,\n name,\n kind: 'local',\n attempts: 1,\n enqueuedAt: startedAt,\n startedAt,\n });\n for (let attempt = 1; ; attempt += 1) {\n // Events are scoped per attempt — a retry starts a clean log, so the checkpoint reflects\n // only the attempt that actually completed (or the final failing one).\n const events: StepEvent[] = [];\n try {\n const invocation: StepInvocation = {\n runId,\n workflow,\n stepName: name,\n seq: current,\n attempt,\n };\n const body = () => fn(createStepLogger(events, host.clock));\n const output = host.interceptStep\n ? await host.interceptStep(invocation, body)\n : await body();\n await host.completeStep({\n runId,\n seq: current,\n name,\n kind: 'local',\n output,\n events,\n attempts: attempt,\n enqueuedAt: startedAt,\n startedAt,\n });\n if (options?.compensate) compensations.push({ name, fn: options.compensate });\n return output;\n } catch (err) {\n if (err instanceof FatalError || attempt >= maxAttempts) {\n await host.failStep({\n runId,\n seq: current,\n name,\n kind: 'local',\n error: {\n message: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n },\n events,\n attempts: attempt,\n enqueuedAt: startedAt,\n startedAt,\n });\n throw err;\n }\n // Wait out the backoff before the next attempt (no-op when backoffMs is unset).\n const wait = backoffDelay(attempt, options);\n if (wait > 0) await new Promise((resolve) => setTimeout(resolve, wait));\n }\n }\n };\n\n // Exactly-once DB step: run the body and write the step checkpoint in ONE store transaction, so the\n // business write commits atomically with the \"done\" marker (a plain step checkpoints AFTER the body,\n // so a crash in between re-runs it). Replay returns the recorded output without re-running.\n const transaction = async <T>(name: string, fn: (tx: unknown) => Promise<T>): Promise<T> => {\n if (!store.transaction) {\n throw new Error(\n 'ctx.transaction needs a store that supports transactions (the SQL adapters do). Use ctx.step for non-transactional work.',\n );\n }\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.name !== name) {\n throw new NonDeterminismError(runId, current, name, existing.name);\n }\n if (existing && existing.status === 'completed') return existing.output as T;\n return store.transaction(async (tx) => {\n const output = await fn(tx.raw);\n const cp = instantCheckpoint({ runId, seq: current, name, kind: 'local', output });\n await tx.saveCheckpoint(cp);\n // Reflect the committed checkpoint in the snapshot, keeping the writeback invariant uniform.\n replay?.set(current, cp);\n return output;\n });\n };\n\n // Shared by sleep / sleepUntil: record a durable timer at this position and suspend until `wakeAt`\n // (epoch ms). The wakeAt is computed by the caller — but only used on the first run; on replay the\n // recorded checkpoint's wakeAt wins, so a clock change can't shift an already-scheduled timer.\n const suspendUntil = async (wakeAt: () => number): Promise<void> => {\n const current = pos.next();\n const now = host.clock();\n const existing = await readCheckpoint(current);\n if (existing) {\n // Timer already recorded: resume if due, otherwise re-suspend cheaply.\n if (now >= (existing.wakeAt ?? 0)) return;\n throw new WorkflowSuspended(existing.wakeAt ?? now);\n }\n const at = wakeAt();\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name: 'sleep', kind: 'sleep', wakeAt: at }),\n );\n throw new WorkflowSuspended(at);\n };\n\n const sleep = (duration: string | number): Promise<void> =>\n suspendUntil(() => host.clock() + parseDuration(duration));\n\n const sleepUntil = (when: Date | number): Promise<void> =>\n suspendUntil(() => (typeof when === 'number' ? when : when.getTime()));\n\n // End this run and hand off to a fresh execution (clean history) with the new input. Terminal —\n // it always throws, so any code after it in the workflow is unreachable.\n const continueAsNew = (input?: unknown): Promise<never> => {\n throw new ContinueAsNew(input);\n };\n\n // NOTE (determinism): a bounded wait consumes TWO logical positions (deadline + wait), an\n // unbounded one consumes ONE. So adding or removing `{ timeoutMs }` on an existing `waitForSignal`\n // shifts the seq of every later step — treat it as a workflow-version change for in-flight runs.\n // Consume a buffered signal (one delivered before this run was waiting), recording it as the\n // signal checkpoint at `seq` so it resumes immediately instead of suspending. Replay-safe: the\n // checkpoint makes the consumption deterministic.\n const consumeBuffered = async <T>(token: string, seq: number): Promise<{ value: T } | null> => {\n const buffered = await store.takeBufferedSignal(token);\n if (!buffered) return null;\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq,\n name: `signal:${token}`,\n kind: 'signal',\n output: buffered.payload,\n }),\n );\n return { value: buffered.payload as T };\n };\n\n const waitForSignal = async <T>(token: string, opts?: { timeoutMs?: number }): Promise<T> => {\n if (opts?.timeoutMs == null) {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as T;\n const buffered = await consumeBuffered<T>(token, current);\n if (buffered) return buffered.value;\n await store.putSignalWaiter({ token, runId, seq: current });\n throw new WorkflowSuspended();\n }\n const timeoutMs = opts.timeoutMs;\n const deadlineSeq = pos.next();\n const waitSeq = pos.next();\n // The deadline is recorded durably as a timer checkpoint so replay knows it; the run also gets a\n // run-level wakeAt (via WorkflowSuspended) so the timer poller resumes it at the deadline.\n const recorded = await readCheckpoint(deadlineSeq);\n const deadline = recorded?.wakeAt ?? host.clock() + timeoutMs;\n if (!recorded) {\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq: deadlineSeq,\n name: `timeout:${token}`,\n kind: 'sleep',\n wakeAt: deadline,\n }),\n );\n }\n const waited = await readCheckpoint(waitSeq);\n if (waited && waited.status === 'completed') return waited.output as T;\n const buffered = await consumeBuffered<T>(token, waitSeq);\n if (buffered) return buffered.value;\n if (host.clock() >= deadline) {\n await store.takeSignalWaiter(token).catch(() => undefined);\n throw new SignalTimeoutError(token, timeoutMs);\n }\n await store.putSignalWaiter({ token, runId, seq: waitSeq });\n throw new WorkflowSuspended(deadline);\n };\n\n // Wait for a named event delivered by engine.publishEvent(name, payload). Like waitForSignal, but\n // name-based pub/sub with optional `match` filtering — the token embeds name + match (see events.ts),\n // so a publish fans out to the runs whose match the payload satisfies.\n const waitForEvent = async <T>(\n name: string,\n opts?: { match?: Record<string, unknown>; timeoutMs?: number },\n ): Promise<T> => {\n if (opts?.timeoutMs == null) {\n const current = pos.next();\n const token = eventToken(name, opts?.match, runId, current);\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as T;\n await store.putSignalWaiter({ token, runId, seq: current });\n throw new WorkflowSuspended();\n }\n const timeoutMs = opts.timeoutMs;\n const deadlineSeq = pos.next();\n const waitSeq = pos.next();\n const token = eventToken(name, opts.match, runId, waitSeq);\n const recorded = await readCheckpoint(deadlineSeq);\n const deadline = recorded?.wakeAt ?? host.clock() + timeoutMs;\n if (!recorded) {\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq: deadlineSeq,\n name: `timeout:event:${name}`,\n kind: 'sleep',\n wakeAt: deadline,\n }),\n );\n }\n const waited = await readCheckpoint(waitSeq);\n if (waited && waited.status === 'completed') return waited.output as T;\n if (host.clock() >= deadline) {\n await store.takeSignalWaiter(token).catch(() => undefined);\n throw new SignalTimeoutError(`event:${name}`, timeoutMs);\n }\n await store.putSignalWaiter({ token, runId, seq: waitSeq });\n throw new WorkflowSuspended(deadline);\n };\n\n // An external task = a checkpointed dispatch + a wait for its async-completion `Completion`\n // (delivered by engine.completeTask/failTask). The whole \"fire at a foreign system, suspend,\n // resume when it reports back\" pattern as one call.\n const task = async <T>(\n name: string,\n dispatch: () => Promise<void>,\n options?: StepOptions,\n ): Promise<T> => {\n await step(`task:dispatch:${name}`, dispatch, options);\n return unwrapCompletion<T>(await waitForSignal(`task:${runId}:${name}`), `task \"${name}\"`);\n };\n\n // Child workflow (await result): start it once, then suspend on a `child:<id>` waiter the child\n // signals on its terminal state (see engine.notifyParent).\n const child = async <T>(\n workflow: WorkflowRef,\n input: unknown,\n options?: string | ChildCallOptions,\n ): Promise<T> => {\n const { childId, priority } = normalizeChildOptions(options);\n const current = pos.next();\n const id = childId ?? `${runId}.child.${current}`;\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') {\n return unwrapCompletion<T>(existing.output, `child \"${id}\"`);\n }\n await store.putSignalWaiter({ token: `child:${id}`, runId, seq: current });\n if (!(await store.getRun(id))) host.startChild(workflowName(workflow), input, id, priority);\n // Make the awaited child visible in the parent's timeline WHILE it runs: a `running` placeholder\n // at this seq with the same `signal:child:<id>` name the signal resolution later overwrites as\n // `completed`. So the dashboard shows the child node (and can inline-expand it) live, instead of\n // it appearing only when it finishes. Written once (skipped on replay, where `existing` is set);\n // `running` is ignored by replay history, so it never short-circuits determinism.\n if (!existing) {\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq: current,\n name: `signal:child:${id}`,\n kind: 'signal',\n status: 'running',\n }),\n );\n }\n throw new WorkflowSuspended();\n };\n\n // Child workflow (fire-and-forget): dispatch it once and return its id WITHOUT suspending. The\n // start is checkpointed at this position so replay returns the same id without re-dispatching, and\n // is idempotent by id, so `child(..., sameId)` later joins the same run rather than starting a new\n // one (start + join scatter-gather).\n const startChild = async (\n workflow: WorkflowRef,\n input: unknown,\n options?: string | ChildCallOptions,\n ): Promise<string> => {\n const { childId, priority } = normalizeChildOptions(options);\n const current = pos.next();\n const id = childId ?? `${runId}.child.${current}`;\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as string;\n if (!(await store.getRun(id))) host.startChild(workflowName(workflow), input, id, priority);\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name: `spawn:${id}`, kind: 'local', output: id }),\n );\n return id;\n };\n\n // Call a durable entity op and await its result: register a reply waiter at this position, dispatch\n // the op with the reply token, and suspend until the entity signals the result back (checkpointed,\n // so replay returns it without re-dispatching).\n const callEntity = async <R>(\n name: string,\n key: string,\n op: string,\n arg?: unknown,\n ): Promise<R> => {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as R;\n const reply = `entityreply:${runId}:${current}`;\n await store.putSignalWaiter({ token: reply, runId, seq: current });\n host.signalEntity?.(name, key, op, arg, reply);\n throw new WorkflowSuspended();\n };\n\n // Send a durable entity op without awaiting a result — dispatched once (checkpointed, replay-safe).\n const signalEntity = async (\n name: string,\n key: string,\n op: string,\n arg?: unknown,\n ): Promise<void> => {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return;\n host.signalEntity?.(name, key, op, arg);\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name: `entitysig:${name}:${key}`, kind: 'local' }),\n );\n };\n\n // A breakpoint = a visible `pending` checkpoint + a signal waiter the dashboard resumes via\n // `engine.continue`. Reuses the signal machinery, so resume overwrites the pending checkpoint\n // with a completed one and the run replays past it.\n const breakpoint = async (label?: string): Promise<void> => {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return;\n if (!existing) {\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq: current,\n name: label ? `breakpoint:${label}` : 'breakpoint',\n kind: 'signal',\n status: 'pending',\n }),\n );\n await store.putSignalWaiter({ token: breakpointToken(runId, current), runId, seq: current });\n }\n throw new WorkflowSuspended();\n };\n\n // Guard an in-place change: a fresh run records a `patch:<id>` marker here and takes the new\n // branch; a run recorded under the OLD code finds a real step at this position instead, so we\n // rewind the logical position (the marker is transparent to it) and return false — its replay\n // reads that old step next and follows the old branch. No position shift → no corruption.\n const patched = async (id: string): Promise<boolean> => {\n const marker = `patch:${id}`;\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing) {\n if (existing.name === marker) return true;\n if (existing.name.startsWith('patch:')) {\n throw new NonDeterminismError(runId, current, marker, existing.name);\n }\n pos.rewind(); // not a marker: an old run's step lives here — give the position back to it\n return false;\n }\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name: marker, kind: 'local', output: true }),\n );\n return true;\n };\n\n // An update point: suspend on a run-scoped `update:<runId>:<name>` token that engine.update\n // delivers to (after its validator passes). Reuses the signal machinery; run-scoped like task/child.\n const onUpdate = <T>(name: string, opts?: { timeoutMs?: number }): Promise<T> =>\n waitForSignal<T>(`update:${runId}:${name}`, opts);\n\n // A queryable named value: a checkpoint whose `name` is `event:<key>`, so the latest value for a\n // key is just the highest-seq such checkpoint (read by engine.getEvent). Replay-idempotent.\n const setEvent = async (key: string, value: unknown): Promise<void> => {\n const current = pos.next();\n const name = `event:${key}`;\n const existing = await readCheckpoint(current);\n if (existing && existing.name !== name) {\n throw new NonDeterminismError(runId, current, name, existing.name);\n }\n if (existing && existing.status === 'completed') return; // replay: already published\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name, kind: 'local', output: value }),\n );\n };\n\n // A durable webhook reserves a logical position NOW to mint a stable token, so the url can be\n // handed to a third party before `wait()` suspends. `wait()` then parks on that same position\n // until the callback lands as engine.signal(token, body) — single position, replay-safe.\n const webhook = <T>(): DurableWebhook<T> => {\n const current = pos.next();\n const token = `wh:${runId}:${current}`;\n const wait = async (): Promise<T> => {\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as T;\n await store.putSignalWaiter({ token, runId, seq: current });\n throw new WorkflowSuspended();\n };\n return { token, url: host.webhookUrl?.(token), wait };\n };\n\n // Deterministic non-deterministic sources: each is a checkpointed local step, so the value is\n // captured on the first run and replayed verbatim (a raw Date.now()/Math.random() inside a\n // workflow would differ across replays and corrupt the run).\n const now = () => step('now', async () => host.clock());\n const random = () => step('random', async () => Math.random());\n const uuid = () => step('uuid', async () => globalThis.crypto.randomUUID());\n\n return {\n runId,\n step,\n transaction,\n callEntity,\n signalEntity,\n sleep,\n sleepUntil,\n continueAsNew,\n waitForSignal,\n waitForEvent,\n task,\n child,\n startChild,\n breakpoint,\n webhook,\n setEvent,\n onUpdate,\n patched,\n now,\n random,\n uuid,\n call: (remote, input, opts) =>\n host.callRemote(runId, pos.next(), remote, input, opts?.queue, opts?.transport, {\n priority: opts?.priority,\n fairnessKey: opts?.fairnessKey,\n }),\n };\n}\n","import { type AdmissionBackend, InMemoryAdmissionBackend } from './admission';\nimport { backoffDelay } from './backoff';\nimport { instantCheckpoint, stepCheckpoint } from './checkpoints';\nimport { type Completion } from './completion';\nimport { parseDuration } from './duration';\nimport { Entities, type EntityConfig } from './entities';\nimport {\n ContinueAsNew,\n FatalError,\n NonDeterminismError,\n RemoteStepTimeout,\n SignalTimeoutError,\n WorkflowSuspended,\n} from './errors';\nimport { EventAccumulators, type EventBatchConfig } from './event-accumulators';\nimport { eventMatchOf, eventMatches, eventPrefix } from './events';\nimport type {\n ControlPlane,\n EngineEvent,\n EngineListener,\n GroupHealth,\n NamedTransport,\n RemoteStepDef,\n RemoteTask,\n RunDispatcher,\n RunQuery,\n RunResult,\n RunStatus,\n SearchAttributes,\n StateStore,\n StepCheckpoint,\n StepError,\n StepEvent,\n StepInterceptor,\n StepInvocation,\n StepKind,\n StepResult,\n Transport,\n UpdateResult,\n UpdateValidator,\n WorkflowCommand,\n WorkflowCtx,\n WorkflowDecision,\n WorkflowExecutor,\n WorkflowRun,\n WorkflowStepEvent,\n} from './interfaces';\nimport type { HistoryEvent } from './interfaces';\nimport { breakpointToken, stepId } from './protocol';\nimport type { QueueConfig } from './queue';\nimport { SingletonGate } from './singleton-gate';\nimport { TransportPool } from './transport-pool';\nimport {\n type Compensation,\n type CtxHost,\n type StepRecord,\n createWorkflowCtx,\n} from './workflow-ctx';\nimport {\n type WorkflowClass,\n type WorkflowInputOf,\n type WorkflowRef,\n workflowName,\n} from './workflow-ref';\n\ntype WorkflowFn = (ctx: WorkflowCtx, input: unknown) => Promise<unknown>;\n\n/** Options for {@link WorkflowEngine.start}. */\nexport interface StartOptions {\n /** Run-scoped tags, merged with the workflow's static `@Workflow({ tags })` onto the run. */\n tags?: string[] | undefined;\n /** Typed, queryable run data stamped on the run (e.g. `{ amount: 200, tier: 'pro' }`). */\n searchAttributes?: SearchAttributes | undefined;\n /**\n * Dispatch priority for a remote run — stamped on the run and carried onto every {@link WorkflowTask}\n * the engine dispatches to advance it. Higher wins; absent = unprioritised. See {@link WorkflowRun.priority}.\n */\n priority?: number | undefined;\n}\n\n/**\n * Serialize runs of a workflow that share a key — a durable, FIFO mutex (e.g. one pipeline per base).\n * Excess runs are admitted in creation order, `limit` at a time; the rest wait (suspended) and retry\n * admission on a timer until a slot frees. Race-free on a consistent store (admission order is the\n * same `(createdAt, id)` view for every instance).\n */\nexport interface SingletonConfig {\n /** Derive the serialization key from the workflow input. */\n key: (input: unknown) => string;\n /** Max concurrent runs sharing the key. Default 1 (a mutex). */\n limit?: number;\n /**\n * Max GATED (waiting-for-admission) runs allowed to queue behind the `limit` in-flight ones. When\n * set, `start` rejects with {@link SingletonQueueFullError} once in-flight + gated reaches\n * `limit + maxQueueDepth` — back-pressure against an unbounded same-key backlog. Omit for the\n * default unbounded queue. Counts `pending`/`running`/`suspended` runs sharing the key.\n */\n maxQueueDepth?: number;\n}\n\n/** Union of a workflow's static tags and a run's start-time tags, de-duplicated, or undefined if none. */\nfunction mergeTags(staticTags?: string[], runTags?: string[]): string[] | undefined {\n if (!staticTags?.length && !runTags?.length) return undefined;\n return [...new Set([...(staticTags ?? []), ...(runTags ?? [])])];\n}\n\n/** A breakpoint checkpoint's `name` is `breakpoint` (or `breakpoint:<label>`). This name — not the\n * reused `signal` kind — is the explicit marker the dashboard and `continue()` detect it by. */\nconst BREAKPOINT = 'breakpoint';\nconst isBreakpoint = (cp: { status: string; name: string }): boolean =>\n cp.status === 'pending' && cp.name.startsWith(BREAKPOINT);\n\ninterface RegisteredWorkflow {\n name: string;\n version: string;\n fn: WorkflowFn;\n /** Static `@Workflow({ tags })` — merged with per-run tags onto each run at start. */\n tags?: string[] | undefined;\n /** Per-key serialization (a durable mutex). See {@link SingletonConfig}. */\n singleton?: SingletonConfig | undefined;\n /** Max wall-clock lifetime (ms) before a run is cancelled by `sweepTimeouts`. */\n executionTimeoutMs?: number | undefined;\n /** Validate the input at start; throw to reject before a run is created. Validator-agnostic. */\n validateInput?: ((input: unknown) => void | Promise<void>) | undefined;\n /** Event names that start a fresh run of this workflow when published. See `publishEvent`. */\n onEvent?: string[] | undefined;\n /** Coalesce `onEvent` triggers: debounce (fire once it's quiet) or batch (fire on size/window). */\n eventBatch?: EventBatchConfig | undefined;\n /** Set for a workflow authored in another SDK (e.g. Python): the engine advances it by dispatching\n * workflow tasks to `executor` instead of running `fn` in-process. See {@link WorkflowExecutor}. */\n remote?: { group: string; executor: WorkflowExecutor };\n}\n\nconst versionKey = (name: string, version: string): string => `${name}@${version}`;\n\n/** The id for the next continuation of a run: `r` → `r~1` → `r~2` … (stable, traceable lineage). */\nfunction nextContinuationId(runId: string): string {\n const m = runId.match(/^(.*)~(\\d+)$/);\n return m ? `${m[1]}~${Number(m[2]) + 1}` : `${runId}~1`;\n}\n\n/** True when version `a` is newer than `b` (numeric when both parse as numbers, else natural sort). */\nfunction isNewerVersion(a: string, b: string): boolean {\n const na = Number(a);\n const nb = Number(b);\n if (!Number.isNaN(na) && !Number.isNaN(nb)) return na > nb;\n return a.localeCompare(b, undefined, { numeric: true }) > 0;\n}\n\n/** What a remote worker hands back: the output plus when it actually began (for queue-wait timing). */\ninterface RemoteResolution {\n output: unknown;\n startedAt?: number | undefined;\n events?: StepEvent[] | undefined;\n}\n\ninterface PendingRemote {\n resolve: (result: RemoteResolution) => void;\n reject: (error: Error) => void;\n}\n\n/** A terminal/suspended transition handed to {@link WorkflowEngine.settleRun}. */\ntype RunOutcome =\n | { kind: 'completed'; output: unknown }\n | { kind: 'failed'; error: StepError }\n | { kind: 'suspended'; wakeAt?: number | undefined };\n\nexport interface WorkflowEngineDeps {\n store: StateStore;\n /** A single task transport. Shorthand for a one-entry `transports` pool (id `default`). */\n transport?: Transport | undefined;\n /**\n * An ordered pool of named transports. The engine dispatches on the first and fails over to the\n * next on a dispatch error; a step pins one via `ctx.call(step, input, { transport: id })`. Use\n * this instead of `transport` for failover / multi-broker setups.\n */\n transports?: NamedTransport[] | undefined;\n /**\n * Cross-instance broadcast pub/sub for lifecycle events + cancellation (see {@link ControlPlane}).\n * Separate from the task `transport`; omit for a single-instance / local-only setup. A transport\n * that can also broadcast may be passed here as well.\n */\n controlPlane?: ControlPlane | undefined;\n /** Epoch-ms clock; injectable for tests. Defaults to `Date.now`. */\n clock?: (() => number) | undefined;\n /**\n * Flow-control admission backend for `ctx.call(step, input, { queue })`. Defaults to an in-process\n * {@link InMemoryAdmissionBackend} (per-instance caps). Inject a store/Redis-backed backend to make\n * concurrency / rate-limit / ordering GLOBAL across engine replicas.\n */\n admission?: AdmissionBackend | undefined;\n /** Unique id for this engine instance, used for recovery leases. Defaults to a random id. */\n instanceId?: string | undefined;\n /** Recovery lease duration in ms — how long this instance owns a run it picked up. Default 30s. */\n leaseMs?: number | undefined;\n /**\n * Cap how many times crash-recovery may pick up the same still-`running` run before giving up and\n * moving it to the `dead` dead-letter state (a poison pill that crashes the process every boot).\n * Omit for unlimited (the default — recovery always retries).\n */\n maxRecoveryAttempts?: number | undefined;\n /**\n * Build the public callback URL for a `ctx.webhook()` token (e.g.\n * ``(t) => `https://api.example.com/durable/webhooks/${t}` ``). Populates\n * {@link DurableWebhook.url}. Omit if you build URLs yourself from the token.\n */\n webhookUrl?: ((token: string) => string) | undefined;\n /**\n * Provide the current W3C `traceparent` to stamp on each dispatched {@link RemoteTask}, so a\n * worker (including the Python SDK) continues the distributed trace. Keep core OTel-free: supply\n * `otelTraceparent` from `@dudousxd/nestjs-durable-otel`, or your own context reader. Omit to send none.\n */\n traceparent?: (() => string | undefined) | undefined;\n /**\n * Provide an opaque context carrier (tenant / user / correlation ids) to attach to each dispatched\n * {@link RemoteTask} as its `context`, so a worker (including the Python SDK) re-exposes it to the\n * step handler — cross-process propagation alongside the {@link traceparent}. Keep core dependency-free:\n * supply this from `@dudousxd/nestjs-context` or your own request-scoped reader. The engine never\n * inspects the returned object's shape. Omit to send none.\n *\n * Re-evaluated at each (re)dispatch — including a retry or a resume that the engine drives AFTER a\n * crash/scale-down, which runs OUTSIDE the originating request scope. On such a path this provider\n * may return empty or stale values (the request-scoped tenant/user is gone). Treat the carrier as\n * best-effort correlation/propagation metadata only — do NOT treat it as an authorization boundary.\n */\n context?: (() => Record<string, unknown> | undefined) | undefined;\n /**\n * Re-hydrate the originating context around a LOCAL step body, so a `@DurableStep` reader sees the\n * tenant / user / correlation ids that were live when the run was started — even on a path the\n * engine drives outside the originating request scope (a resume after crash/scale-down, a timer).\n * Given the carrier produced by {@link context} (may be empty/undefined) and the step body `fn`, it\n * runs `fn` with that context ambiently established (e.g. inside `@dudousxd/nestjs-context`'s ALS)\n * and returns its result. Keep core dependency-free: supply this from the nestjs wiring (which owns\n * nestjs-context) or your own ALS bridge. The handler signature is unchanged — re-hydration is\n * ambient. Default: passthrough (`(_, fn) => fn()`), so behavior is byte-identical when unset.\n */\n rehydrate?: (<T>(carrier: Record<string, unknown> | undefined, fn: () => T) => T) | undefined;\n /**\n * Attempts for each saga compensation when the run fails (a transient undo — e.g. a refund API\n * hiccup — gets another try). Default 1 (no retry). Compensations must be idempotent.\n */\n compensationRetries?: number | undefined;\n /**\n * Persist a `running` checkpoint when a local step's body begins, so an in-flight step shows up\n * in the dashboard (and a fresh page load / REST query) the moment it starts — not only once it\n * completes. The `step.started` lifecycle event is emitted either way (the live SSE view always\n * sees the start); this flag only controls the extra checkpoint write. Default `true`. Set\n * `false` on hot paths with many short local steps to halve their checkpoint writes — you keep\n * the live event but lose reload-survivable in-flight visibility.\n */\n trackStepStart?: boolean | undefined;\n /**\n * Where a freshly-`start`ed run executes (see {@link RunDispatcher}). Defaults to in-process: the\n * run executes on this instance asynchronously (a microtask), so `start` returns without blocking.\n * Pass a no-op dispatcher on a caller that must NOT run workflows (e.g. an API/dashboard pod), and\n * run `runPending` on a worker pod to pick those up; or a broker-backed one for a worker pool.\n */\n runDispatcher?: RunDispatcher | undefined;\n}\n\n/**\n * The orchestrator. Owns workflow state and replays runs deterministically: each step's\n * result is checkpointed, so on resume a completed step returns its saved output instead of\n * re-executing. Remote steps are dispatched over the Transport; their results checkpoint the\n * same way local steps do.\n */\nexport class WorkflowEngine {\n private readonly store: StateStore;\n /** Ordered transport pool (dispatch + failover). Empty = no remote steps. */\n private readonly pool: TransportPool;\n private readonly controlPlane?: ControlPlane | undefined;\n private readonly clock: () => number;\n private readonly instanceId: string;\n private readonly leaseMs: number;\n private readonly maxRecoveryAttempts?: number | undefined;\n private readonly webhookUrl?: ((token: string) => string) | undefined;\n private readonly traceparent?: (() => string | undefined) | undefined;\n private readonly context?: (() => Record<string, unknown> | undefined) | undefined;\n /** Establish the originating context ambiently around a local step body (see {@link WorkflowEngineDeps.rehydrate}). Default passthrough. */\n private readonly rehydrate: <T>(carrier: Record<string, unknown> | undefined, fn: () => T) => T;\n private readonly compensationRetries: number;\n /** Persist a `running` checkpoint at the start of a local step body (see {@link WorkflowEngineDeps.trackStepStart}). */\n private readonly trackStepStart: boolean;\n /** Where a freshly-started run executes — in-process by default (see {@link RunDispatcher}). */\n private readonly runDispatcher: RunDispatcher;\n\n /** Per-key serialization for singleton workflows (admission, back-pressure, notify-on-release). */\n private readonly singletons: SingletonGate;\n /** Every registered workflow, keyed by `name@version` — so old versions stay runnable. */\n private readonly workflows = new Map<string, RegisteredWorkflow>();\n /** The newest registered version per workflow name — used to `start` new runs. */\n private readonly latest = new Map<string, RegisteredWorkflow>();\n /** Event name → workflow names started when that event is published (see `onEvent`). */\n private readonly eventTriggers = new Map<string, Set<string>>();\n /** Durable-entity subsystem (registers the `__entity` runner; see `registerEntity`). */\n private readonly entities: Entities;\n /** Event debounce/batch accumulators (register the `__evt_*` runners; see `accumulators.route`). */\n private readonly accumulators: EventAccumulators;\n /** In-flight remote steps awaiting a worker result, keyed by stepId. */\n private readonly pending = new Map<string, PendingRemote>();\n /** Per-step \"reset the liveness timer\" callbacks, called when a heartbeat arrives. */\n private readonly heartbeatResets = new Map<string, () => void>();\n private readonly listeners = new Set<EngineListener>();\n /** Step interceptors (onion middleware around real local-step execution), first = outermost. */\n private readonly interceptors: StepInterceptor[] = [];\n /** Callbacks notified (on any instance) when a run is cancelled — for cooperative cancellation. */\n private readonly cancelListeners = new Set<(runId: string) => void>();\n /** Callbacks notified when a run is enqueued elsewhere — for low-latency cross-pod dispatch. */\n private readonly enqueuedListeners = new Set<(runId: string) => void>();\n /** Notified when a run is dead-lettered (moved to `dead`) — a hook for a DLQ handler. */\n private readonly deadListeners = new Set<(run: WorkflowRun) => void>();\n /** Validators gating `engine.update`, keyed by `<workflow>:<updateName>`. */\n private readonly updateValidators = new Map<string, UpdateValidator>();\n /** Runs being cancelled WITH saga compensation — see `cancel({ compensate: true })`. */\n private readonly cancelRequested = new Set<string>();\n /** Flow-control admission backend for remote steps (see {@link registerQueue}). */\n private readonly admission: AdmissionBackend;\n /** Runs on THIS instance blocked on admission, by queue — woken early on a freed-slot signal. */\n private readonly queueWaiters = new Map<string, Set<string>>();\n /** Which queue a dispatched step took a slot from, by stepId — so the result can release it. */\n private readonly stepQueue = new Map<string, string>();\n /** Executions currently in flight, so a graceful shutdown can wait for them to settle. */\n private readonly inflight = new Set<Promise<RunResult>>();\n private draining = false;\n\n constructor(deps: WorkflowEngineDeps) {\n this.store = deps.store;\n this.pool = new TransportPool(\n deps.transports ?? (deps.transport ? [{ id: 'default', transport: deps.transport }] : []),\n );\n this.controlPlane = deps.controlPlane;\n this.clock = deps.clock ?? Date.now;\n this.admission = deps.admission ?? new InMemoryAdmissionBackend(this.clock);\n // Wake this instance's admission-blocked runs the moment a slot frees anywhere in the fleet,\n // instead of waiting for their retry tick. Best-effort (the retry tick remains the guarantee).\n this.admission.onFreed?.((queue) => this.wakeQueueWaiters(queue));\n this.instanceId = deps.instanceId ?? globalThis.crypto.randomUUID();\n this.leaseMs = deps.leaseMs ?? 30_000;\n this.maxRecoveryAttempts = deps.maxRecoveryAttempts;\n this.webhookUrl = deps.webhookUrl;\n this.traceparent = deps.traceparent;\n this.context = deps.context;\n // Default passthrough: with no bridge supplied, a local step body runs exactly as before.\n this.rehydrate = deps.rehydrate ?? ((_carrier, fn) => fn());\n this.compensationRetries = Math.max(1, deps.compensationRetries ?? 1);\n this.trackStepStart = deps.trackStepStart ?? true;\n // Default: execute the run on this instance, asynchronously, so `start` never blocks on the body.\n // A failed pickup is swallowed here (the run stays `pending` for a `runPending` poll to retry);\n // run failures themselves are handled inside `execute` and surfaced as the run's `failed` state.\n this.runDispatcher = deps.runDispatcher ?? {\n dispatch: (runId) => queueMicrotask(() => void this.runOne(runId).catch(() => {})),\n };\n this.singletons = new SingletonGate({\n store: this.store,\n clock: this.clock,\n dispatch: (runId) => {\n this.runDispatcher.dispatch(runId);\n },\n configFor: (run) =>\n (\n this.workflows.get(versionKey(run.workflow, run.workflowVersion)) ??\n this.latest.get(run.workflow)\n )?.singleton,\n });\n this.pool.bind(\n async (result) => {\n // In-memory path (a `timeoutMs` step awaiting on THIS instance): resolve its pending promise.\n const waiter = this.pending.get(result.stepId);\n if (waiter) {\n this.pending.delete(result.stepId);\n if (result.status === 'completed') {\n waiter.resolve({\n output: result.output,\n startedAt: result.startedAt,\n events: result.events,\n });\n } else {\n waiter.reject(new RemoteStepError(result.error));\n }\n return;\n }\n // Durable path: no in-memory waiter (the step suspended the run, possibly on another\n // instance) → complete the checkpoint and resume the run here.\n await this.completeRemoteResult(result);\n },\n // A heartbeat for an in-flight long step resets its liveness window (see callRemote).\n async (beat) => {\n this.heartbeatResets.get(beat.stepId)?.();\n },\n // A remote workflow worker streams each local step's lifecycle (running → completed/failed) so\n // it's checkpointed live, not all-at-once when the long turn ends.\n async (event) => {\n await this.persistStepEvent(event);\n },\n );\n // Control plane: re-broadcast lifecycle events from OTHER instances to this instance's\n // subscribers (cross-pod live-tail), and act on cancellations issued elsewhere. A broker may\n // echo our own publish back — ignore those (we already handled them locally) to avoid duplicates.\n this.controlPlane?.onControl((msg) => {\n if (msg.from === this.instanceId) return;\n if (msg.kind === 'event') {\n // `at` may be a string after JSON transit (Redis) — normalize back to a Date.\n this.deliver({ ...msg.event, at: new Date(msg.event.at) });\n } else if (msg.kind === 'cancel') {\n this.notifyCancelled(msg.runId);\n } else if (msg.kind === 'enqueued') {\n // A run was enqueued on another instance — let worker subscribers pick it up immediately\n // instead of waiting for the next poll. (Self-broadcasts are already filtered above.)\n for (const fn of this.enqueuedListeners) {\n try {\n fn(msg.runId);\n } catch {\n /* an enqueue listener must not break the engine */\n }\n }\n }\n });\n this.accumulators = new EventAccumulators(this);\n this.entities = new Entities(this);\n }\n\n /**\n * Register a **durable entity** (a virtual object): a keyed actor whose `handlers` run **serialized\n * per key** over **durable state**, exactly once. Drive it with `signalEntity` (fire) /\n * `ctx.callEntity` (call + await result) and read its state with `getEntityState`. See {@link Entities}.\n */\n registerEntity<S>(name: string, config: EntityConfig<S>): void {\n this.entities.register(name, config);\n }\n\n /** Send an operation to an entity (fire-and-forget). Ordered + exactly-once per key. */\n signalEntity(name: string, key: string, op: string, arg?: unknown): Promise<void> {\n return this.entities.signal(name, key, op, arg);\n }\n\n /** Read an entity's current durable state (published after each op), or undefined if it has none yet. */\n getEntityState<S = unknown>(name: string, key: string): Promise<S | undefined> {\n return this.entities.getState<S>(name, key);\n }\n\n /**\n * Be notified when a run is enqueued on ANOTHER instance (via the control plane), so a worker can\n * pick it up at once — e.g. `engine.onEnqueued((runId) => engine.runOne(runId))`. Returns an\n * unsubscribe function. Only wire this on instances that should execute runs (workers).\n */\n onEnqueued(listener: (runId: string) => void): () => void {\n this.enqueuedListeners.add(listener);\n return () => this.enqueuedListeners.delete(listener);\n }\n\n /** Fire cooperative-cancellation listeners for `runId` (a worker bridge aborts in-flight work). */\n private notifyCancelled(runId: string): void {\n for (const fn of this.cancelListeners) {\n try {\n fn(runId);\n } catch {\n /* a cancel listener must not break the engine */\n }\n }\n }\n\n /**\n * Register a workflow version. Register multiple versions of the same name to keep in-flight\n * runs working across a breaking change: old runs resume on the version they started on, new\n * runs start on the newest registered version.\n */\n register(\n name: string,\n version: string,\n fn: WorkflowFn,\n opts?: {\n tags?: string[] | undefined;\n singleton?: SingletonConfig | undefined;\n executionTimeout?: string | number | undefined;\n validateInput?: ((input: unknown) => void | Promise<void>) | undefined;\n onEvent?: string[] | undefined;\n eventBatch?: EventBatchConfig | undefined;\n },\n ): void {\n const registered: RegisteredWorkflow = {\n name,\n version,\n fn,\n tags: opts?.tags,\n singleton: opts?.singleton,\n executionTimeoutMs:\n opts?.executionTimeout != null ? parseDuration(opts.executionTimeout) : undefined,\n validateInput: opts?.validateInput,\n onEvent: opts?.onEvent,\n eventBatch: opts?.eventBatch,\n };\n this.workflows.set(versionKey(name, version), registered);\n const current = this.latest.get(name);\n if (!current || isNewerVersion(version, current.version)) this.latest.set(name, registered);\n for (const event of opts?.onEvent ?? []) {\n const subscribers = this.eventTriggers.get(event) ?? new Set<string>();\n subscribers.add(name);\n this.eventTriggers.set(event, subscribers);\n }\n }\n\n /**\n * Register a workflow whose body runs in another SDK (e.g. Python). The engine owns the run exactly\n * as for a TS workflow — it persists checkpoints, recovers, runs timers — but advances it by handing\n * the run's history to `executor` (which dispatches a {@link WorkflowTask} to the worker) and applying\n * the {@link WorkflowDecision} the worker's replay returns. The worker never touches the store.\n */\n registerRemote(\n name: string,\n version: string,\n opts: {\n group: string;\n executor: WorkflowExecutor;\n tags?: string[];\n singleton?: SingletonConfig;\n executionTimeout?: string | number;\n validateInput?: (input: unknown) => void | Promise<void>;\n },\n ): void {\n const registered: RegisteredWorkflow = {\n name,\n version,\n // A remote workflow has no in-process body; execute() branches on `remote` before this is read.\n fn: () => {\n throw new Error(`workflow ${name} is remote — it has no in-process body`);\n },\n tags: opts.tags,\n singleton: opts.singleton,\n executionTimeoutMs:\n opts.executionTimeout != null ? parseDuration(opts.executionTimeout) : undefined,\n validateInput: opts.validateInput,\n remote: { group: opts.group, executor: opts.executor },\n };\n this.workflows.set(versionKey(name, version), registered);\n const current = this.latest.get(name);\n if (!current || isNewerVersion(version, current.version)) this.latest.set(name, registered);\n }\n\n /**\n * Register a flow-control queue referenced by `ctx.call(step, input, { queue })`. Caps concurrent\n * in-flight steps and/or the admission rate; blocked calls re-suspend and retry, so the limit is\n * durable. Per engine instance (see {@link QueueConfig}). Registering the same name replaces it.\n */\n registerQueue(config: QueueConfig): void {\n this.admission.register(config);\n }\n\n /** Subscribe to lifecycle events. Returns an unsubscribe function. */\n subscribe(listener: EngineListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Register a {@link StepInterceptor} — onion middleware run around the real execution of every\n * local `ctx.step` (timing, logging, tracing, error enrichment, context propagation). First\n * registered is outermost; interceptors fire only when a step executes, never on replay. Returns\n * an unsubscribe function.\n */\n use(interceptor: StepInterceptor): () => void {\n this.interceptors.push(interceptor);\n return () => {\n const i = this.interceptors.indexOf(interceptor);\n if (i >= 0) this.interceptors.splice(i, 1);\n };\n }\n\n /**\n * Fold the registered interceptors around a local step body (identity when there are none), then\n * run the whole thing inside the re-hydrated originating context. The carrier is read at execution\n * time from {@link context} — the SAME reader stamped on dispatched remote tasks — so a local step\n * sees the live tenant / user / trace ids ambiently (via the {@link rehydrate} bridge). Default\n * `rehydrate` is a passthrough, so this is byte-identical to a bare body call when unwired.\n */\n private interceptStep<T>(invocation: StepInvocation, body: () => Promise<T>): Promise<T> {\n const carrier = this.context?.();\n const run = (): Promise<T> => {\n if (this.interceptors.length === 0) return body();\n const chain = this.interceptors.reduceRight<() => Promise<unknown>>(\n (next, interceptor) => () => interceptor(invocation, next),\n body as () => Promise<unknown>,\n );\n return chain() as Promise<T>;\n };\n return this.rehydrate(carrier, run);\n }\n\n /**\n * Be notified when a run is cancelled — on ANY instance, via the transport control plane. A\n * worker bridge can use this for cooperative cancellation: abort the in-flight work for `runId`\n * instead of finishing it just to have the result discarded. Returns an unsubscribe function.\n */\n onCancel(listener: (runId: string) => void): () => void {\n this.cancelListeners.add(listener);\n return () => this.cancelListeners.delete(listener);\n }\n\n /**\n * Be notified when a run is **dead-lettered** — moved to `dead` after exceeding\n * `maxRecoveryAttempts`. The listener receives the dead run (status `dead`, with its error), so a\n * DLQ handler can do something other than just leaving it parked: alert, push to a real queue, or\n * start a dead-letter workflow (e.g. `engine.onDead((run) => engine.start('pipeline-dlq', run, ...))`).\n * Returns an unsubscribe function.\n */\n onDead(listener: (run: WorkflowRun) => void): () => void {\n this.deadListeners.add(listener);\n return () => this.deadListeners.delete(listener);\n }\n\n private notifyDead(run: WorkflowRun): void {\n for (const fn of this.deadListeners) {\n try {\n fn(run);\n } catch {\n /* a dead-letter handler must not break recovery */\n }\n }\n }\n\n /** Emit a locally-produced lifecycle event: deliver to subscribers AND broadcast it on the\n * control plane so other instances (e.g. a dashboard pod) can live-tail this run. */\n private emit(event: Omit<EngineEvent, 'at'>): void {\n const full: EngineEvent = { ...event, at: new Date() };\n this.deliver(full);\n if (this.controlPlane) {\n void this.controlPlane\n .publishControl({ kind: 'event', event: full, from: this.instanceId })\n .catch(() => {\n // control-plane delivery is best-effort observability; never break execution\n });\n }\n }\n\n /** Deliver an event to local subscribers only (no re-broadcast) — used for both locally-produced\n * events and ones received from the control plane, so an event shows up once on every instance. */\n private deliver(event: EngineEvent): void {\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch {\n // a misbehaving subscriber must never break workflow execution\n }\n }\n }\n\n async start<C extends WorkflowClass>(\n workflow: C,\n input: WorkflowInputOf<C>,\n runId: string,\n opts?: StartOptions,\n ): Promise<RunResult>;\n async start<TInput>(\n workflow: string,\n input: TInput,\n runId: string,\n opts?: StartOptions,\n ): Promise<RunResult>;\n async start(\n workflow: WorkflowRef,\n input: unknown,\n runId: string,\n opts?: StartOptions,\n ): Promise<RunResult> {\n const name = workflowName(workflow);\n const registered = this.latest.get(name);\n if (!registered) throw new Error(`workflow ${name} is not registered`);\n // Validate the input up front — a bad payload is rejected before any run is created.\n await registered.validateInput?.(input);\n // Idempotent by run id: a redelivered trigger (at-least-once queues) or a scheduler re-tick for\n // the same id is a no-op, returning the existing run's state instead of starting a duplicate.\n const prior = await this.store.getRun(runId);\n if (prior) {\n return { runId, status: prior.status, output: prior.output, error: prior.error };\n }\n const now = new Date();\n // A singleton workflow stamps a `singleton:<key>` tag so the admission gate (in execute) can find\n // the other in-flight runs sharing the key via a tag+status query.\n const tags = mergeTags(\n registered.tags,\n registered.singleton\n ? [...(opts?.tags ?? []), this.singletons.tag(registered.singleton, input)]\n : opts?.tags,\n );\n // Singleton back-pressure: reject a start that would grow the same-key backlog past\n // `limit + maxQueueDepth` (no-op when no maxQueueDepth is configured).\n if (registered.singleton) {\n await this.singletons.assertCapacity(name, registered.singleton, input);\n }\n const run: WorkflowRun = {\n id: runId,\n workflow: name,\n workflowVersion: registered.version,\n status: 'pending',\n input,\n tags,\n searchAttributes: opts?.searchAttributes,\n priority: opts?.priority,\n createdAt: now,\n updatedAt: now,\n };\n await this.store.createRun(run);\n // The run is durably enqueued; a dispatcher (in-process by default) executes it — `start` does\n // NOT run the body inline. Await the terminal/suspended state with `waitForRun(runId)` if needed.\n await this.runDispatcher.dispatch(runId);\n // Nudge worker instances to pick it up now instead of on their next poll (no-op without a control\n // plane; self-receipt is filtered, so it only helps OTHER pods — e.g. an API pod's enqueue).\n if (this.controlPlane) {\n void this.controlPlane\n .publishControl({ kind: 'enqueued', runId, from: this.instanceId })\n .catch(() => undefined);\n }\n return { runId, status: 'pending' };\n }\n\n /** Read a run's current persisted state (or null if unknown). A thin pass-through to the store. */\n getRun(runId: string): Promise<WorkflowRun | null> {\n return this.store.getRun(runId);\n }\n\n async resume(runId: string): Promise<RunResult> {\n const run = await this.store.getRun(runId);\n if (!run) throw new Error(`run ${runId} not found`);\n // A definitively-finished run must not be re-executed (e.g. a worker result landing after the\n // run was cancelled, or a duplicate resume) — that would replay the body and clobber the\n // terminal state. `failed` is intentionally NOT terminal here: retry resumes a failed run.\n if (run.status === 'cancelled' || run.status === 'completed' || run.status === 'dead') {\n return { runId, status: run.status, output: run.output, error: run.error };\n }\n // Pin to the version the run STARTED on — replay is positional, so running a changed\n // workflow body against old checkpoints would corrupt the run.\n const registered = this.workflows.get(versionKey(run.workflow, run.workflowVersion));\n if (!registered) {\n throw new Error(\n `workflow ${run.workflow}@${run.workflowVersion} is not registered — keep the prior version deployed so in-flight runs can drain (skew protection)`,\n );\n }\n return this.track(this.execute(run, registered.fn));\n }\n\n /** Track an in-flight execution so {@link drain} can wait for it. */\n private track(p: Promise<RunResult>): Promise<RunResult> {\n this.inflight.add(p);\n void p.finally(() => this.inflight.delete(p));\n return p;\n }\n\n /**\n * Graceful shutdown: stop picking up new runs (recovery/timer become no-ops) and wait for\n * in-flight executions to settle, up to `timeoutMs`. Call from your app's shutdown hook so a\n * deploy hands off cleanly instead of leaving runs to the lease timeout.\n */\n async drain(timeoutMs = 10_000): Promise<void> {\n this.draining = true;\n if (this.inflight.size === 0) return;\n const timer = new Promise<void>((resolve) => {\n const t = setTimeout(resolve, timeoutMs);\n (t as { unref?: () => void }).unref?.();\n });\n await Promise.race([Promise.allSettled([...this.inflight]), timer]);\n }\n\n /**\n * Cancel in-flight runs that have outlived their workflow's `executionTimeout`. Call it from the\n * timer poller alongside {@link resumeDueTimers}. A timed-out run is moved to `cancelled` with an\n * `execution_timeout` error (terminal, so a late step result can't resurrect it).\n */\n async sweepTimeouts(now: number = this.clock()): Promise<void> {\n for (const reg of new Set(this.latest.values())) {\n if (reg.executionTimeoutMs == null) continue;\n const deadline = now - reg.executionTimeoutMs;\n const inflight = [\n ...(await this.store.listRuns({ workflow: reg.name, status: 'running' })),\n ...(await this.store.listRuns({ workflow: reg.name, status: 'suspended' })),\n ];\n for (const run of inflight) {\n if (run.createdAt.getTime() > deadline) continue;\n const error = { message: 'execution timeout', code: 'execution_timeout' };\n await this.store.updateRun(run.id, { status: 'cancelled', error, updatedAt: new Date() });\n this.emit({ type: 'run.failed', runId: run.id, workflow: run.workflow, error });\n }\n }\n }\n\n /**\n * Resume every run left incomplete by a crash or deploy. Called on boot. Completed steps\n * replay from their checkpoints, so only the work that had not finished runs again.\n */\n async recoverIncomplete(nowMs: number = this.clock()): Promise<RunResult[]> {\n if (this.draining) return [];\n const results: RunResult[] = [];\n for (const run of await this.store.listIncompleteRuns()) {\n // A live worker renews its lease, so an acquirable lease means the run is genuinely orphaned\n // (its worker crashed). Skip the ones still owned.\n const acquired = await this.store.tryLockRun(\n run.id,\n this.instanceId,\n nowMs + this.leaseMs,\n nowMs,\n );\n if (!acquired) continue;\n // Count the attempt / dead-letter a poison pill past maxRecoveryAttempts.\n const settled = await this.countRecovery(run);\n if (settled) {\n results.push(settled);\n continue;\n }\n // Re-enqueue rather than resume inline: recovery must NOT block (boot, or a poll tick) on a\n // long workflow step. A dispatcher/worker re-runs it, replaying its checkpoints.\n await this.store.releaseRunLock(run.id);\n await this.store.updateRun(run.id, { status: 'pending', updatedAt: new Date() });\n await this.runDispatcher.dispatch(run.id);\n results.push({ runId: run.id, status: 'pending' });\n }\n return results;\n }\n\n /**\n * Per-recovery bookkeeping (called once the lease is held): count the attempt, or — past\n * `maxRecoveryAttempts` — move a poison pill to the `dead` dead-letter state. Returns a terminal\n * result to skip the resume, or `undefined` to proceed.\n */\n private async countRecovery(run: WorkflowRun): Promise<RunResult | undefined> {\n const attempts = (run.recoveryAttempts ?? 0) + 1;\n if (this.maxRecoveryAttempts != null && attempts > this.maxRecoveryAttempts) {\n const error = {\n message: `run exceeded maxRecoveryAttempts (${this.maxRecoveryAttempts}) — moved to dead-letter`,\n code: 'max_recovery_attempts',\n };\n await this.store.updateRun(run.id, { status: 'dead', error, updatedAt: new Date() });\n await this.store.releaseRunLock(run.id);\n this.emit({ type: 'run.failed', runId: run.id, workflow: run.workflow, error });\n this.notifyDead({ ...run, status: 'dead', error, recoveryAttempts: attempts });\n return { runId: run.id, status: 'dead', error };\n }\n // Count BEFORE resuming, so a crash mid-resume still advances the counter.\n await this.store.updateRun(run.id, { recoveryAttempts: attempts, updatedAt: new Date() });\n return undefined;\n }\n\n /**\n * Resume every suspended run whose durable timer is due. Call periodically (a poller) and on\n * boot. A run still not due re-suspends cheaply without running new work.\n */\n async resumeDueTimers(nowMs: number = this.clock()): Promise<RunResult[]> {\n return this.resumeLeased(await this.store.listDueTimers(nowMs), nowMs);\n }\n\n /**\n * Lease and execute one run by id — the worker side of dispatch. Acquires the recovery lease (so\n * exactly one instance runs it), then resumes the body. Returns the result, or null if another\n * instance holds the lease or the engine is draining. The default in-process dispatcher calls this;\n * a broker-backed worker calls it per consumed run id.\n */\n async runOne(runId: string): Promise<RunResult | null> {\n if (this.draining) return null;\n const nowMs = this.clock();\n const acquired = await this.store.tryLockRun(\n runId,\n this.instanceId,\n nowMs + this.leaseMs,\n nowMs,\n );\n if (!acquired) return null;\n return this.resume(runId);\n }\n\n /**\n * Re-enqueue a run for a worker to (re-)execute — the dispatch-model **retry**. Sets it back to\n * `pending`, clears any stale lease, and dispatches; a worker resumes it (replaying its checkpoints,\n * re-attempting the failed step). Returns the enqueued state immediately — never runs the body\n * inline — or null if the run is unknown. The dashboard \"retry\" goes through here so it can't block\n * the HTTP request on workflow execution.\n */\n async requeue(runId: string): Promise<RunResult | null> {\n const run = await this.store.getRun(runId);\n if (!run) return null;\n await this.store.releaseRunLock(runId);\n await this.store.updateRun(runId, { status: 'pending', updatedAt: new Date() });\n await this.runDispatcher.dispatch(runId);\n return { runId, status: 'pending' };\n }\n\n /**\n * **Fix-and-replay**: re-run a run (typically a `dead`/`failed` one) with a corrected `input`, as a\n * fresh run with clean history. It's a NEW run — `newRunId` defaults to `<runId>~retry~<uuid>` — so\n * the original stays inspectable. Returns the new run's id, or null if `runId` is unknown.\n */\n async retryWithInput(\n runId: string,\n input: unknown,\n newRunId?: string,\n ): Promise<{ runId: string } | null> {\n const run = await this.store.getRun(runId);\n if (!run) return null;\n const id = newRunId ?? `${runId}~retry~${globalThis.crypto.randomUUID().slice(0, 8)}`;\n await this.start(run.workflow, input, id, { tags: run.tags });\n return { runId: id };\n }\n\n /**\n * Pick up and execute every `pending` run — the poll-based side of dispatch for a worker pod with\n * no broker. Runs enqueued by other pods (or by a caller using a no-op dispatcher) sit `pending`\n * in the store until polled; leasing ensures exactly one pod runs each. Call periodically alongside\n * {@link resumeDueTimers}.\n */\n async runPending(nowMs: number = this.clock()): Promise<RunResult[]> {\n // Oldest-first (FIFO), capped per call so a backlog drains over several polls without one sweep\n // fetching unboundedly. A run not picked up this tick is picked up the next.\n return this.resumeLeased(await this.store.listPendingRuns(100), nowMs);\n }\n\n /**\n * Resolve once `runId` reaches a settled state — terminal (completed/failed/cancelled/dead) or\n * suspended (handed off to a timer/signal/event). The async counterpart to dispatch: pair it with\n * `start` when a call site needs the outcome — `await start(...); const r = await waitForRun(id)`.\n */\n waitForRun(runId: string, opts?: { timeoutMs?: number }): Promise<RunResult> {\n const isSettled = (s: RunStatus): boolean => s !== 'pending' && s !== 'running';\n const toResult = (run: WorkflowRun): RunResult => ({\n runId,\n status: run.status,\n output: run.output,\n error: run.error,\n });\n return new Promise<RunResult>((resolve, reject) => {\n let done = false;\n let off: () => void = () => {};\n const timer =\n opts?.timeoutMs != null\n ? setTimeout(() => {\n if (done) return;\n done = true;\n off();\n reject(new Error(`waitForRun(${runId}) timed out after ${opts.timeoutMs}ms`));\n }, opts.timeoutMs)\n : undefined;\n const finish = (run: WorkflowRun): void => {\n if (done) return;\n done = true;\n if (timer) clearTimeout(timer);\n off();\n resolve(toResult(run));\n };\n const check = (): void => {\n void this.store.getRun(runId).then((run) => {\n if (run && isSettled(run.status)) finish(run);\n });\n };\n // React only to this run's settling events (not its every step event), and subscribe BEFORE the\n // initial read so a run that settles in between isn't missed.\n off = this.subscribe((ev) => {\n if (\n ev.runId === runId &&\n (ev.type === 'run.completed' || ev.type === 'run.failed' || ev.type === 'run.suspended')\n ) {\n check();\n }\n });\n check();\n });\n }\n\n /**\n * Resume each run only if this instance can acquire its recovery lease — so when several\n * replicas recover or poll at once, each run is picked up by exactly one of them.\n */\n private async resumeLeased(\n runs: WorkflowRun[],\n nowMs: number = this.clock(),\n onLocked?: (run: WorkflowRun) => Promise<RunResult | undefined>,\n ): Promise<RunResult[]> {\n if (this.draining) return []; // shutting down — don't pick up new runs\n const results: RunResult[] = [];\n for (const run of runs) {\n const acquired = await this.store.tryLockRun(\n run.id,\n this.instanceId,\n nowMs + this.leaseMs,\n nowMs,\n );\n if (!acquired) continue;\n // A per-run hook (recovery counting / dead-lettering) may settle the run terminally instead.\n const settled = onLocked ? await onLocked(run) : undefined;\n results.push(settled ?? (await this.resume(run.id)));\n }\n return results;\n }\n\n /**\n * Deliver an external signal to the run waiting on `token` and resume it with `payload`.\n * Returns the run result, or null if no run is waiting for that token.\n */\n /**\n * Publish a named event. It does two things, and returns how many runs it touched (the sum):\n * 1. **Resumes** every in-flight run waiting on it via `ctx.waitForEvent(name, { match })` whose\n * match the payload satisfies (fan-out, vs `signal`'s point-to-point token).\n * 2. **Starts** a fresh run of every workflow registered with `onEvent: [name]`, passing the\n * payload as input. Idempotent by `evt:<id>:<workflow>` — pass `opts.id` to dedupe redeliveries\n * of the same logical event (default: a fresh uuid, so each publish triggers once).\n */\n async publishEvent(name: string, payload: unknown, opts?: { id?: string }): Promise<number> {\n let touched = 0;\n const waiters = await this.store.listSignalWaiters(eventPrefix(name));\n for (const w of waiters) {\n if (eventMatches(payload, eventMatchOf(w.token))) {\n await this.signal(w.token, payload);\n touched += 1;\n }\n }\n const subscribers = this.eventTriggers.get(name);\n if (subscribers?.size) {\n const eventId = opts?.id ?? globalThis.crypto.randomUUID();\n for (const workflow of subscribers) {\n // A subscriber that rejects the payload (validateInput) must not block the others or the\n // waiters — its run simply never starts, mirroring fire-and-forget dead-letter routing.\n try {\n const batch = this.latest.get(workflow)?.eventBatch;\n if (batch) {\n // Coalesce: route the event into a per-workflow accumulator (one long-lived run that\n // debounces/batches and then starts the target with the collected payload(s)).\n await this.accumulators.route(workflow, batch, payload);\n } else {\n await this.start(workflow, payload, `evt:${eventId}:${workflow}`);\n }\n touched += 1;\n } catch {\n // skip this subscriber\n }\n }\n }\n return touched;\n }\n\n async signal(token: string, payload: unknown): Promise<RunResult | null> {\n const waiter = await this.store.takeSignalWaiter(token);\n if (!waiter) {\n // No one is waiting yet — buffer it so the next `waitForSignal(token)` consumes it instead of\n // dropping it (reliable signals; the basis of `signalWithStart`).\n await this.store.bufferSignal(token, payload);\n return null;\n }\n await this.store.saveCheckpoint(\n instantCheckpoint({\n runId: waiter.runId,\n seq: waiter.seq,\n name: `signal:${token}`,\n kind: 'signal',\n output: payload,\n }),\n );\n return this.resume(waiter.runId);\n }\n\n /**\n * Ensure a run exists for `runId`, then deliver a signal to it — atomically race-free thanks to\n * signal buffering: if the run is new (or busy / not yet waiting), the signal is buffered and\n * consumed when it reaches `waitForSignal(token)`. The canonical **durable-entity / accumulator**\n * pattern: one long-lived run per key (the `runId`) that loops on `waitForSignal`, fed events by\n * many `signalWithStart` calls. `start` is idempotent by `runId`, so concurrent callers converge on\n * one run. (Use a per-run `token`, e.g. derived from `runId`, so the signal targets this entity.)\n */\n async signalWithStart(\n workflow: WorkflowRef,\n input: unknown,\n runId: string,\n signal: { token: string; payload?: unknown },\n opts?: StartOptions,\n ): Promise<{ runId: string }> {\n // `start` is overloaded per ref kind (class | string); a `WorkflowRef` union fits neither\n // overload, so resolve to the string overload (the engine handles both at runtime).\n await this.start(workflow as string, input, runId, opts); // idempotent: no-op if run exists\n await this.signal(signal.token, signal.payload);\n return { runId };\n }\n\n /**\n * Report the result of a `ctx.task(name, …)` back to its run (async completion). The external\n * worker that the task dispatched to calls this when done; the run resumes with `result`. Returns\n * null if no run is waiting on the task (e.g. a duplicate/late delivery) — a safe no-op.\n */\n async completeTask(runId: string, name: string, result: unknown): Promise<RunResult | null> {\n return this.signal(`task:${runId}:${name}`, {\n ok: true,\n value: result,\n } satisfies Completion<unknown>);\n }\n\n /** Report that a `ctx.task` failed — the run resumes and throws a FatalError at the task. */\n async failTask(runId: string, name: string, error: string): Promise<RunResult | null> {\n return this.signal(`task:${runId}:${name}`, { ok: false, error } satisfies Completion<never>);\n }\n\n /**\n * Notify a parent that's waiting on `runId` as a child of its terminal outcome (the `ctx.child`\n * rendezvous). A no-op when no parent is waiting, so `execute()` can call it on every run without\n * knowing about the child feature.\n */\n private notifyParent(runId: string, completion: Completion<unknown>): void {\n void this.signal(`child:${runId}`, completion).catch(() => undefined);\n }\n\n /**\n * Cancel a run (e.g. from the dashboard). Returns null if the run does not exist. Pass\n * `{ compensate: true }` to undo the saga first: the suspended run is resumed so its completed\n * steps' compensations run in reverse (visible as `compensate:<step>` events), then it's marked\n * cancelled. Without it, cancellation is immediate (no undo).\n */\n async cancel(runId: string, opts?: { compensate?: boolean }): Promise<RunResult | null> {\n const run = await this.store.getRun(runId);\n if (!run) return null;\n // Already finished — nothing to cancel (and don't clobber a completed/dead run). This also stops\n // the child cascade below from looping on already-cancelled runs.\n if (run.status === 'completed' || run.status === 'cancelled' || run.status === 'dead') {\n return { runId, status: run.status, output: run.output, error: run.error };\n }\n // Compensating cancel: resume the run with a cancellation pending — replay re-registers the saga,\n // and at the suspension point execute() runs the undo and marks it cancelled. Run that resume in\n // the BACKGROUND so the caller (e.g. an HTTP request) never blocks on replaying the workflow +\n // compensations. `execute` holds the run's lease, so this can't double-run one a live worker owns\n // (its lease acquire fails and it no-ops); the broadcast tells that worker to abort cooperatively.\n if (opts?.compensate && (run.status === 'suspended' || run.status === 'running')) {\n this.cancelRequested.add(runId);\n if (this.controlPlane) {\n void this.controlPlane\n .publishControl({ kind: 'cancel', runId, from: this.instanceId })\n .catch(() => undefined);\n }\n queueMicrotask(() => {\n void this.resume(runId)\n .then(() => this.notifyCancelled(runId))\n .catch(() => undefined);\n });\n await this.cancelChildren(runId, opts);\n return { runId, status: run.status };\n }\n const error = { message: 'cancelled' };\n await this.store.updateRun(runId, { status: 'cancelled', error, updatedAt: new Date() });\n this.emit({ type: 'run.failed', runId, workflow: run.workflow, error });\n await this.cancelChildren(runId, opts);\n // Notify local cancel listeners now (a worker on this pod), and broadcast so the instance/worker\n // actually running this run learns of it and can abort cooperatively (the store already records\n // `cancelled`, but a busy worker won't re-read it).\n this.notifyCancelled(runId);\n if (this.controlPlane) {\n void this.controlPlane\n .publishControl({ kind: 'cancel', runId, from: this.instanceId })\n .catch(() => undefined);\n }\n // A cancelled singleton run frees its slot — wake the next gated waiter now (notify-on-release).\n void this.singletons.wakeNext(run).catch(() => undefined);\n return { runId, status: 'cancelled', error };\n }\n\n /**\n * Bulk-cancel every run matching a filter — e.g. cancel all `order` runs tagged `vip`, or every run\n * whose `tier` search attribute is `free`. The filter is a {@link RunQuery} (workflow / status / tag\n * / search-attribute predicates), so it reuses the same matching the dashboard list uses. Each match\n * is run through {@link cancel}, so the same plumbing applies per run: child cascade, the optional\n * saga `compensate`, local cancel listeners, and the control-plane broadcast that tells the owning\n * worker to abort. Returns one {@link RunResult} per matched run (already-finished matches report\n * their terminal status — `cancel` is a no-op on them, never clobbering a completed/dead run).\n */\n async cancelWhere(\n filter: Omit<RunQuery, 'limit' | 'offset'>,\n opts?: { compensate?: boolean },\n ): Promise<RunResult[]> {\n const runs = await this.store.listRuns(filter);\n const results: RunResult[] = [];\n for (const run of runs) {\n const r = await this.cancel(run.id, opts);\n if (r) results.push(r);\n }\n return results;\n }\n\n /**\n * Hard-delete a run and its entire subtree. Unlike {@link cancel} (which marks a run `cancelled`\n * but keeps it as history), delete REMOVES the run and all its rows (checkpoints, signal waiters,\n * search-attribute rows) — it vanishes from {@link getRun} and {@link listRuns}. Use it to purge a\n * finished run whose data is being deleted (e.g. a pipeline run whose result rows are cleared).\n *\n * Cascades depth-first via {@link getRunChildren} so children are gone before the parent (no\n * orphaned child runs). Prefer {@link cancel} first for a live run — deleting one mid-flight orphans\n * its worker (its next checkpoint write fails). Returns the number of runs deleted (0 if absent).\n */\n async deleteRun(runId: string): Promise<number> {\n const run = await this.store.getRun(runId);\n if (!run) return 0;\n // Collect children BEFORE deleting this run's checkpoints (getRunChildren reads them).\n let deleted = 0;\n for (const childId of await this.getRunChildren(runId)) {\n deleted += await this.deleteRun(childId);\n }\n await this.store.deleteRun(runId);\n return deleted + 1;\n }\n\n /**\n * Cascade cancellation to a run's children — both awaited (`ctx.child`, found via its live\n * `child:<id>` waiter) and fire-and-forget (`ctx.startChild`, found via its `spawn:<id>`\n * checkpoint). Recursive, so a whole subtree is cancelled; the terminal guard in `cancel` stops it\n * at finished / already-cancelled runs (no loops, no re-cancel).\n */\n private async cancelChildren(\n parentRunId: string,\n opts?: { compensate?: boolean },\n ): Promise<void> {\n for (const id of await this.getRunChildren(parentRunId)) {\n await this.cancel(id, opts).catch(() => undefined);\n }\n }\n\n /**\n * The ids of the runs a run spawned — both awaited (`ctx.child`) and fire-and-forget\n * (`ctx.startChild`, found via its `spawn:<id>` checkpoint). The canonical parent→children edge,\n * used for both cancellation cascades and the dashboard run-tree.\n *\n * An awaited child is discovered two ways, because the live `child:<id>` waiter only exists WHILE\n * the parent is suspended on it: the waiter resolves and is consumed the moment the child settles,\n * so a completed parent (or a completed awaited child) would otherwise drop out of the tree. The\n * `signal:child:<id>` checkpoint (the placeholder written when the parent first awaits the child,\n * overwritten as completed/failed when it settles) persists across completion, so we read both and\n * dedupe — the edge stays stable for a finished run, not just a live one.\n */\n async getRunChildren(parentRunId: string): Promise<string[]> {\n const childIds = new Set<string>();\n for (const w of await this.store.listSignalWaiters('child:')) {\n if (w.runId === parentRunId) childIds.add(w.token.slice('child:'.length));\n }\n // Targeted read: only the `signal:child:` / `spawn:` checkpoints, not the whole history. Falls\n // back to a full listCheckpoints + in-JS prefix scan for a custom store that omits the method.\n const prefixes = ['signal:child:', 'spawn:'];\n const childCheckpoints = this.store.listCheckpointsByNamePrefix\n ? await this.store.listCheckpointsByNamePrefix(parentRunId, prefixes)\n : (await this.store.listCheckpoints(parentRunId)).filter((cp) =>\n prefixes.some((p) => cp.name.startsWith(p)),\n );\n for (const cp of childCheckpoints) {\n if (cp.name.startsWith('signal:child:')) childIds.add(cp.name.slice('signal:child:'.length));\n if (cp.name.startsWith('spawn:') && typeof cp.output === 'string') childIds.add(cp.output);\n }\n return [...childIds];\n }\n\n /** The worker groups this engine dispatches to: every registered remote workflow's group, plus any\n * `extra` the caller declares. Local-step groups (a group consumed by in-process `@DurableStep`\n * workers, e.g. `pipeline`) aren't derivable from registrations — pass them via `extra` so a group\n * with backlog and ZERO workers is still reported (the alert case has no heartbeat to discover). */\n knownGroups(extra: string[] = []): string[] {\n const groups = new Set<string>(extra);\n for (const def of this.workflows.values()) {\n if (def.remote?.group) groups.add(def.remote.group);\n }\n return [...groups];\n }\n\n /** Per-group worker health (queue backlog + live worker heartbeats). Covers {@link knownGroups}\n * (so a registered group with backlog and ZERO workers still reports — the alert case) UNION the\n * groups discovered from live heartbeats (so a local-step group like `pipeline`, not derivable\n * from registrations, shows once its workers beat). Empty when no transport can introspect health\n * (only the BullMQ transport implements `groupHealth`). */\n async workerHealth(extra: string[] = []): Promise<GroupHealth[]> {\n const groups = new Set([...this.knownGroups(extra), ...(await this.pool.listWorkerGroups())]);\n const out: GroupHealth[] = [];\n for (const group of groups) {\n const health = await this.pool.groupHealth(group);\n if (health) out.push(health);\n }\n return out;\n }\n\n /**\n * Persist a streamed local-step lifecycle event from a remote workflow worker (see\n * {@link WorkflowStepEvent}). A Python `@workflow` runs its `ctx.step`s inline over one turn that\n * can last minutes; the worker streams each step's start/finish so the engine checkpoints it LIVE —\n * a step shows `running` the moment its body begins, then resolves to `completed`/`failed` with its\n * real wall-clock window and sub-process events — instead of every step appearing at once when the\n * turn ends. The turn's final `recordStep` command re-persists the same (runId, seq) checkpoint\n * idempotently, so this is purely additive observability and never changes the run's outcome.\n */\n private async persistStepEvent(event: WorkflowStepEvent): Promise<void> {\n const startedAt = new Date(event.startedAt);\n if (event.phase === 'running') {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: event.runId,\n seq: event.seq,\n name: event.name,\n kind: 'local',\n status: 'running',\n events: event.events,\n attempts: 1,\n enqueuedAt: startedAt,\n startedAt,\n finishedAt: startedAt, // placeholder until the step settles\n }),\n );\n this.emit({\n type: 'step.started',\n runId: event.runId,\n seq: event.seq,\n name: event.name,\n kind: 'local',\n });\n return;\n }\n const failed = event.phase === 'failed';\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: event.runId,\n seq: event.seq,\n name: event.name,\n kind: 'local',\n status: failed ? 'failed' : 'completed',\n output: failed ? undefined : event.output,\n error: failed ? event.error : undefined,\n events: event.events,\n attempts: 1,\n enqueuedAt: startedAt,\n startedAt,\n finishedAt: event.finishedAt != null ? new Date(event.finishedAt) : new Date(),\n }),\n );\n this.emit({\n type: failed ? 'step.failed' : 'step.completed',\n runId: event.runId,\n seq: event.seq,\n name: event.name,\n kind: 'local',\n output: failed ? undefined : event.output,\n error: failed ? event.error : undefined,\n });\n }\n\n /**\n * Announce a local step's body has begun and (when `trackStepStart`) checkpoint it as `running`,\n * so it's visible in flight rather than appearing only on completion. The checkpoint is a\n * placeholder overwritten by {@link completeStep}/{@link failStep}; it never short-circuits replay\n * (only `completed` does), so a crash mid-body just re-runs the step. The `step.started` event\n * fires regardless — the live SSE view sees the start even with persistence off.\n */\n private async startStep(step: StepRecord): Promise<void> {\n if (this.trackStepStart) {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n status: 'running',\n input: step.input,\n events: step.events,\n attempts: step.attempts,\n workerGroup: step.workerGroup,\n enqueuedAt: step.enqueuedAt,\n startedAt: step.startedAt,\n finishedAt: step.startedAt, // placeholder until the body settles\n }),\n );\n }\n this.emit({\n type: 'step.started',\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n });\n }\n\n /** Checkpoint a finished step and announce it — the two things that must always happen together. */\n private async completeStep(step: StepRecord & { output: unknown }): Promise<void> {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n status: 'completed',\n input: step.input,\n output: step.output,\n events: step.events,\n attempts: step.attempts,\n workerGroup: step.workerGroup,\n enqueuedAt: step.enqueuedAt,\n startedAt: step.startedAt,\n finishedAt: new Date(),\n }),\n );\n this.emit({\n type: 'step.completed',\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n output: step.output,\n queueMs: step.startedAt.getTime() - step.enqueuedAt.getTime(),\n durationMs: Date.now() - step.startedAt.getTime(),\n });\n }\n\n /** Checkpoint a step that failed terminally, so the failure point is visible (not just the run). */\n private async failStep(step: StepRecord & { error: StepError }): Promise<void> {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n status: 'failed',\n input: step.input,\n error: step.error,\n events: step.events,\n attempts: step.attempts,\n workerGroup: step.workerGroup,\n enqueuedAt: step.enqueuedAt,\n startedAt: step.startedAt,\n finishedAt: new Date(),\n }),\n );\n this.emit({\n type: 'step.failed',\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n error: step.error,\n queueMs: step.startedAt.getTime() - step.enqueuedAt.getTime(),\n durationMs: Date.now() - step.startedAt.getTime(),\n });\n }\n\n private async execute(run: WorkflowRun, fn: WorkflowFn): Promise<RunResult> {\n const registered = this.workflows.get(versionKey(run.workflow, run.workflowVersion));\n // Hold the lease for the WHOLE execution — whatever path got us here (leased sweep, a signal, a\n // remote result, a dashboard action). The leased sweeps already own it; the event-driven paths\n // don't, so acquire it here. If another instance owns it, don't double-run. While we run, renew\n // the lease periodically so a long run keeps it (a crashed worker's lease still expires and is\n // reclaimed by periodic recovery).\n const lockNow = this.clock();\n if (run.lockedBy !== this.instanceId || (run.lockedUntil ?? 0) <= lockNow) {\n if (\n !(await this.store.tryLockRun(run.id, this.instanceId, lockNow + this.leaseMs, lockNow))\n ) {\n return { runId: run.id, status: run.status };\n }\n }\n const renew = setInterval(\n () => {\n void this.store\n .renewRunLock(run.id, this.instanceId, this.clock() + this.leaseMs)\n .catch(() => undefined);\n },\n Math.max(50, Math.floor(this.leaseMs / 2)),\n );\n renew.unref?.();\n try {\n // A remote (e.g. Python) workflow is advanced by dispatching workflow tasks, not by running an\n // in-process body — but everything around it (lease, recovery, timers, the resume that lands us\n // here on a step result) is identical, so it branches here under the same lease.\n const result = registered?.remote\n ? await this.runRemoteExecution(run, registered)\n : await this.runExecution(run, fn, registered);\n // Notify-on-release: a singleton run that just reached a terminal state freed a slot — wake the\n // next gated waiter(s) now instead of waiting for the ~1s retry timer. Fire-and-forget so it\n // never blocks the settling run; the durable timer is still the cross-instance/crash fallback.\n if (\n registered?.singleton &&\n (result.status === 'completed' ||\n result.status === 'failed' ||\n result.status === 'cancelled' ||\n result.status === 'dead')\n ) {\n void this.singletons.wakeNext(run).catch(() => undefined);\n }\n return result;\n } finally {\n clearInterval(renew);\n }\n }\n\n /**\n * Advance a remote (cross-SDK) workflow one turn: hand its history to the executor (which dispatches\n * a workflow task to the worker and awaits its replay) and apply the decision. Mirrors\n * {@link runExecution}'s settle/suspend; the lease is held by {@link execute}. The result that lands\n * us back here (a remote step finished, a timer fired) goes through `resume` like any TS workflow.\n */\n /**\n * Apply a terminal/suspended transition once: persist the new run status, emit the matching\n * lifecycle event, and (on completion/failure) wake a waiting parent. Both the TS and remote\n * executors funnel their completed/failed/suspended outcomes through here so a status update can\n * never drift from its event or `notifyParent` call. Does NOT touch the run lock — each executor\n * keeps its own lease handling (the TS executor's `finally`, the remote path's caller).\n */\n private async settleRun(run: WorkflowRun, outcome: RunOutcome): Promise<RunResult> {\n const updatedAt = new Date();\n if (outcome.kind === 'completed') {\n // Clear any error from an earlier failed-then-retried attempt — a completed run is a success.\n await this.store.updateRun(run.id, {\n status: 'completed',\n output: outcome.output,\n error: undefined,\n updatedAt,\n });\n this.emit({\n type: 'run.completed',\n runId: run.id,\n workflow: run.workflow,\n output: outcome.output,\n });\n void this.notifyParent(run.id, { ok: true, value: outcome.output });\n return { runId: run.id, status: 'completed', output: outcome.output };\n }\n if (outcome.kind === 'failed') {\n await this.store.updateRun(run.id, { status: 'failed', error: outcome.error, updatedAt });\n this.emit({\n type: 'run.failed',\n runId: run.id,\n workflow: run.workflow,\n error: outcome.error,\n });\n void this.notifyParent(run.id, { ok: false, error: outcome.error.message });\n return { runId: run.id, status: 'failed', error: outcome.error };\n }\n await this.store.updateRun(run.id, { status: 'suspended', wakeAt: outcome.wakeAt, updatedAt });\n this.emit({ type: 'run.suspended', runId: run.id, workflow: run.workflow });\n return { runId: run.id, status: 'suspended' };\n }\n\n private async runRemoteExecution(\n run: WorkflowRun,\n registered: RegisteredWorkflow,\n ): Promise<RunResult> {\n const remote = registered.remote as NonNullable<RegisteredWorkflow['remote']>;\n if (run.status === 'pending') {\n await this.store.updateRun(run.id, { status: 'running', updatedAt: new Date() });\n run.status = 'running';\n this.emit({ type: 'run.started', runId: run.id, workflow: run.workflow });\n }\n if (registered.singleton && !(await this.singletons.admit(run, registered.singleton))) {\n const wakeAt = this.singletons.retryWakeAt();\n await this.store.updateRun(run.id, { status: 'suspended', wakeAt, updatedAt: new Date() });\n this.emit({ type: 'run.suspended', runId: run.id, workflow: run.workflow });\n await this.store.releaseRunLock(run.id);\n return { runId: run.id, status: 'suspended' };\n }\n\n const history = await this.remoteHistory(run.id);\n let decision: WorkflowDecision;\n try {\n decision = await remote.executor.advance(run, history);\n } catch (err) {\n const error = {\n message: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n };\n await this.store.updateRun(run.id, { status: 'failed', error, updatedAt: new Date() });\n this.emit({ type: 'run.failed', runId: run.id, workflow: run.workflow, error });\n return { runId: run.id, status: 'failed', error };\n }\n\n if (decision.status === 'completed') {\n // Persist the local steps THIS turn ran before marking the run done. A workflow that runs\n // straight to completion in a single turn (every step inline, never suspending — e.g. a Python\n // @workflow whose body is a sequence of ctx.step calls) emits ALL its recordStep commands on\n // this terminal turn; without applying them the run shows `completed` with zero recorded steps.\n // Only this turn's NEW steps are present (prior turns' steps replay as `found`, emitting no\n // command), so there's no duplication.\n await this.applyCommands(run, decision.commands);\n return this.settleRun(run, { kind: 'completed', output: decision.output });\n }\n if (decision.status === 'failed') {\n // Same as completed: persist the steps this turn ran — including the failed one (the worker\n // records a failed-step command before raising) — so the dashboard shows WHERE it failed.\n await this.applyCommands(run, decision.commands);\n return this.settleRun(run, {\n kind: 'failed',\n error: decision.error ?? { message: 'workflow failed' },\n });\n }\n\n if (decision.status === 'cancelled') {\n // The worker bailed at an op boundary because the run was cancelled mid-turn — `cancel` already\n // set status=cancelled, cascaded to children and emitted the lifecycle event. Persist the steps\n // that DID run this turn (partial progress / where it stopped) and reassert `cancelled`\n // (idempotent with `cancel`'s write; preserves the existing error). The point is to NOT resurrect\n // the run to `suspended` or flip it to `failed` — both of which a normal turn result would do.\n await this.applyCommands(run, decision.commands);\n await this.store.updateRun(run.id, { status: 'cancelled', updatedAt: new Date() });\n return { runId: run.id, status: 'cancelled' };\n }\n\n // continue: persist any local steps the replay ran, dispatch the blocking ops, then suspend. When\n // those resolve (a result lands, a timer fires) `resume` brings us back for the next turn.\n const wakeAt = await this.applyCommands(run, decision.commands);\n return this.settleRun(run, { kind: 'suspended', wakeAt });\n }\n\n /** The run's resolved durable ops as replay inputs: completed/failed steps + elapsed timers. */\n private async remoteHistory(runId: string): Promise<HistoryEvent[]> {\n const checkpoints = await this.store.listCheckpoints(runId);\n const kindOf: Record<StepKind, HistoryEvent['kind']> = {\n remote: 'call',\n local: 'step',\n sleep: 'timer',\n signal: 'signal',\n };\n const events: HistoryEvent[] = [];\n for (const cp of checkpoints) {\n if (cp.status === 'completed' || cp.status === 'failed') {\n // A child run resolves THROUGH the signal machinery (a `child:<id>` waiter notified on the\n // child's terminal state), so its checkpoint is kind `signal` with a `signal:child:` name and\n // a Completion payload. Surface it as a `child` event with the value/error unwrapped.\n if (cp.kind === 'signal' && cp.name.startsWith('signal:child:')) {\n const completion = cp.output as Completion<unknown> | undefined;\n events.push({\n seq: cp.seq,\n kind: 'child',\n output: completion?.ok ? completion.value : undefined,\n error:\n completion && completion.ok === false ? { message: completion.error } : undefined,\n });\n continue;\n }\n events.push({\n seq: cp.seq,\n kind: kindOf[cp.kind] ?? 'step',\n // A signal checkpoint's name is the internal `signal:<token>`, not the workflow-level signal\n // name the replay used — omit it so the replay matches on seq + kind (its determinism anchor).\n name: cp.kind === 'signal' ? undefined : cp.name,\n output: cp.status === 'completed' ? cp.output : undefined,\n error: cp.status === 'failed' ? cp.error : undefined,\n });\n } else if (cp.kind === 'sleep' && cp.wakeAt != null && cp.wakeAt <= this.clock()) {\n // a still-`pending` sleep whose deadline has passed reads as a resolved timer on replay.\n events.push({ seq: cp.seq, kind: 'timer', name: cp.name });\n }\n }\n return events.sort((a, b) => a.seq - b.seq);\n }\n\n /** Apply a turn's commands: persist recorded local steps, dispatch remote calls, schedule timers.\n * Returns the earliest timer deadline to suspend on (or undefined — suspended on a result). */\n private async applyCommands(\n run: WorkflowRun,\n commands: WorkflowCommand[],\n ): Promise<number | undefined> {\n let wakeAt: number | undefined;\n for (const cmd of commands) {\n const at = new Date();\n const id = stepId(run.id, cmd.seq);\n if (cmd.kind === 'recordStep') {\n // Prefer the step's real wall-clock window + sub-process events (carried by the command, and\n // already streamed live via persistStepEvent) so the checkpoint shows a true duration and its\n // p-process trail — not a 0ms placeholder. Fall back to apply-time for older workers.\n const startedAt = cmd.startedAt != null ? new Date(cmd.startedAt) : at;\n const finishedAt = cmd.finishedAt != null ? new Date(cmd.finishedAt) : at;\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n kind: 'local',\n status: cmd.error ? 'failed' : 'completed',\n output: cmd.output,\n error: cmd.error,\n events: cmd.events,\n attempts: 1,\n enqueuedAt: startedAt,\n startedAt,\n finishedAt,\n }),\n );\n this.emit({\n type: cmd.error ? 'step.failed' : 'step.completed',\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n kind: 'local',\n output: cmd.output,\n error: cmd.error,\n });\n } else if (cmd.kind === 'call') {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n kind: 'remote',\n status: 'pending',\n input: cmd.input,\n attempts: 1,\n workerGroup: cmd.group,\n enqueuedAt: at,\n startedAt: at,\n finishedAt: at,\n }),\n );\n await this.pool.dispatch(\n {\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n stepId: id,\n group: cmd.group,\n input: cmd.input,\n traceparent: this.traceparent?.(),\n context: this.context?.(),\n attempt: 1,\n },\n undefined,\n );\n this.emit({\n type: 'step.started',\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n kind: 'remote',\n });\n } else if (cmd.kind === 'sleep') {\n const deadline = this.clock() + cmd.ms;\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: run.id,\n seq: cmd.seq,\n name: `sleep:${cmd.seq}`,\n kind: 'sleep',\n status: 'pending',\n attempts: 1,\n wakeAt: deadline,\n enqueuedAt: at,\n startedAt: at,\n finishedAt: at,\n }),\n );\n wakeAt = wakeAt == null ? deadline : Math.min(wakeAt, deadline);\n } else if (cmd.kind === 'waitSignal') {\n // Park on a signal: register a waiter at this seq so engine.signal(token) lands the resolving\n // `signal` checkpoint here and resumes the run. The token is the signal name, so an external\n // engine.signal(name, payload) delivers it. If the signal was already delivered (buffered\n // before the workflow reached this point — e.g. signalWithStart), resolve it now and re-drive\n // on a macrotask, AFTER this turn suspends and frees the run lock (a re-entrant resume bails).\n const buffered = await this.store.takeBufferedSignal(cmd.signal);\n if (buffered) {\n await this.store.saveCheckpoint(\n instantCheckpoint({\n runId: run.id,\n seq: cmd.seq,\n name: `signal:${cmd.signal}`,\n kind: 'signal',\n output: buffered.payload,\n }),\n );\n setTimeout(() => void this.resume(run.id).catch(() => undefined), 0);\n } else {\n await this.store.putSignalWaiter({ token: cmd.signal, runId: run.id, seq: cmd.seq });\n }\n } else if (cmd.kind === 'startChild') {\n // Start a child run and await it (the worker's ctx.start_child suspends until the child's\n // result is in history). Mirror the in-process `ctx.child`: register a `child:<id>` waiter at\n // this seq — the child notifies it on its terminal state (engine.notifyParent) — then start the\n // child once, deferred so a fast child can't reentrantly resume this still-suspending parent,\n // and id-idempotent so replay/recovery never double-starts it.\n const childId = `${run.id}.child.${cmd.seq}`;\n await this.store.putSignalWaiter({\n token: `child:${childId}`,\n runId: run.id,\n seq: cmd.seq,\n });\n if (!(await this.store.getRun(childId))) {\n queueMicrotask(\n () => void this.start(cmd.workflow, cmd.input, childId).catch(() => undefined),\n );\n }\n } else {\n throw new Error(\n `remote workflow command '${(cmd as { kind: string }).kind}' is not supported yet`,\n );\n }\n }\n return wakeAt;\n }\n\n /** The run body, lease held + renewed by {@link execute}. */\n private async runExecution(\n run: WorkflowRun,\n fn: WorkflowFn,\n registered: RegisteredWorkflow | undefined,\n ): Promise<RunResult> {\n // First execution of an enqueued run: mark it running and announce the start, BEFORE the singleton\n // gate — `singletons.admit` only counts `running`/`suspended` runs, so a still-`pending` run could\n // never be admitted. A resumed run is already past `pending`, so this fires exactly once.\n if (run.status === 'pending') {\n await this.store.updateRun(run.id, { status: 'running', updatedAt: new Date() });\n run.status = 'running';\n this.emit({ type: 'run.started', runId: run.id, workflow: run.workflow });\n }\n // Singleton admission gate: if this run shares its key with `limit` older in-flight runs, wait\n // (suspend on a short timer) until a slot frees instead of running now. Re-checked on each resume.\n if (registered?.singleton && !(await this.singletons.admit(run, registered.singleton))) {\n const wakeAt = this.singletons.retryWakeAt();\n await this.store.updateRun(run.id, { status: 'suspended', wakeAt, updatedAt: new Date() });\n this.emit({ type: 'run.suspended', runId: run.id, workflow: run.workflow });\n await this.store.releaseRunLock(run.id);\n return { runId: run.id, status: 'suspended' };\n }\n // Saga compensations registered by completed steps; run in reverse if the run later fails.\n const compensations: Compensation[] = [];\n // Load this run's checkpoints ONCE and key them by seq, so replaying the completed prefix reads\n // from memory instead of one `getCheckpoint` SELECT per primitive (the O(N²) replay-reads fix).\n // Read once at execution start: a checkpoint written AFTER this snapshot (the signal/timer/child\n // this resume wakes on, or one written later in this same execution) is absent from the map, and\n // the ctx falls back to the live store for any absent seq — so replay semantics are unchanged.\n const snapshot = await this.store.listCheckpoints(run.id);\n const replay = new Map<number, StepCheckpoint>();\n for (const cp of snapshot) replay.set(cp.seq, cp);\n const ctx = createWorkflowCtx(this.ctxHostFor(replay), run.id, compensations, run.workflow);\n try {\n const output = await fn(ctx, run.input);\n return this.settleRun(run, { kind: 'completed', output });\n } catch (err) {\n if (err instanceof ContinueAsNew) {\n // Hand off to a fresh execution with a clean history: complete this run, then start the next\n // (`<id>~N`) with the new input. Deferred + idempotent by the continuation id, so a crash\n // mid-handoff re-derives the same next run instead of forking.\n await this.store.updateRun(run.id, {\n status: 'completed',\n output: undefined,\n error: undefined,\n updatedAt: new Date(),\n });\n this.emit({ type: 'run.completed', runId: run.id, workflow: run.workflow });\n void this.notifyParent(run.id, { ok: true, value: undefined });\n const nextId = nextContinuationId(run.id);\n queueMicrotask(\n () => void this.start(run.workflow, err.input, nextId).catch(() => undefined),\n );\n return { runId: run.id, status: 'completed' };\n }\n if (err instanceof WorkflowSuspended) {\n // A compensating cancel resumed this run to reach here: the replay re-registered the saga,\n // so undo the completed steps in reverse and mark it cancelled instead of re-suspending.\n if (this.cancelRequested.has(run.id)) {\n this.cancelRequested.delete(run.id);\n for (let i = compensations.length - 1; i >= 0; i -= 1) {\n const comp = compensations[i];\n if (comp) await this.runCompensation(run, comp);\n }\n const error = { message: 'cancelled' };\n await this.store.updateRun(run.id, { status: 'cancelled', error, updatedAt: new Date() });\n this.emit({ type: 'run.failed', runId: run.id, workflow: run.workflow, error });\n return { runId: run.id, status: 'cancelled', error };\n }\n return this.settleRun(run, { kind: 'suspended', wakeAt: err.wakeAt });\n }\n const error = {\n message: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n };\n // Saga: undo completed steps in reverse, each retried up to `compensationRetries`. Outcomes\n // are emitted as `compensate:<step>` step events so a stranded undo is VISIBLE (not silently\n // swallowed) in the dashboard/telescope; a failing one is still skipped so it can't mask the\n // original failure or strand the rest. (Compensations should be idempotent.)\n for (let i = compensations.length - 1; i >= 0; i -= 1) {\n const comp = compensations[i];\n if (!comp) continue;\n await this.runCompensation(run, comp);\n }\n return this.settleRun(run, { kind: 'failed', error });\n } finally {\n // Release the recovery lease once the run reaches a terminal/suspended state, so the\n // next instance (or the timer poller) can pick it up promptly.\n await this.store.releaseRunLock(run.id);\n }\n }\n\n /**\n * Run one saga compensation, retried up to `compensationRetries`, emitting a `compensate:<step>`\n * step event for its outcome so a stranded undo is visible. Never throws — a permanently-failing\n * compensation is skipped so it can't mask the original failure.\n */\n private async runCompensation(run: WorkflowRun, comp: Compensation): Promise<void> {\n const name = `compensate:${comp.name}`;\n for (let attempt = 1; attempt <= this.compensationRetries; attempt += 1) {\n const startedAt = Date.now();\n try {\n await comp.fn();\n this.emit({\n type: 'step.completed',\n runId: run.id,\n workflow: run.workflow,\n name,\n kind: 'local',\n durationMs: Date.now() - startedAt,\n });\n return;\n } catch (err) {\n if (attempt >= this.compensationRetries) {\n this.emit({\n type: 'step.failed',\n runId: run.id,\n workflow: run.workflow,\n name,\n kind: 'local',\n error: { message: err instanceof Error ? err.message : String(err) },\n durationMs: Date.now() - startedAt,\n });\n }\n }\n }\n }\n\n /** The seam handed to {@link createWorkflowCtx}: the authoring API reaches durability + lifecycle\n * (checkpointing, dispatch, child start) through this, so the ctx primitives live in their own\n * module and the engine stays the orchestrator. */\n private ctxHostFor(replay?: Map<number, StepCheckpoint>): CtxHost {\n return {\n store: this.store,\n replay,\n clock: this.clock,\n webhookUrl: this.webhookUrl,\n startStep: (s) => this.startStep(s),\n completeStep: (s) => this.completeStep(s),\n failStep: (s) => this.failStep(s),\n callRemote: (runId, seq, step, input, queue, transport, admission) =>\n this.callRemote(runId, seq, step, input, queue, transport, replay, admission),\n // Defer so a fast child can't reentrantly resume a still-running parent.\n startChild: (workflow, input, id, priority) => {\n queueMicrotask(\n () => void this.start(workflow, input, id, { priority }).catch(() => undefined),\n );\n },\n signalEntity: (name, key, op, arg, reply) => {\n queueMicrotask(\n () => void this.entities.dispatch(name, key, op, arg, reply).catch(() => undefined),\n );\n },\n interceptStep: (invocation, body) => this.interceptStep(invocation, body),\n };\n }\n\n /**\n * Resume a run paused at a {@link WorkflowCtx.breakpoint} (e.g. the dashboard \"continue\" button).\n * Finds the run's pending breakpoint checkpoint and signals it. Returns null if the run isn't\n * paused at a breakpoint.\n */\n async continue(runId: string): Promise<RunResult | null> {\n const checkpoints = await this.store.listCheckpoints(runId);\n const bp = checkpoints.find(isBreakpoint);\n if (!bp) return null;\n return this.signal(breakpointToken(runId, bp.seq), undefined);\n }\n\n /**\n * Read the latest value a run published for `key` via {@link WorkflowCtx.setEvent} — a\n * side-effect-free query of a live (or finished) run's state. Returns `undefined` if the run\n * never published that key. The suspend-model counterpart of a Temporal query.\n */\n async getEvent<TValue = unknown>(runId: string, key: string): Promise<TValue | undefined> {\n const name = `event:${key}`;\n // Targeted read: the highest-seq checkpoint for this name is the most recent value (a re-published\n // key overwrites at a higher seq), matching the old \"last in seq order wins\" scan. Falls back to a\n // full listCheckpoints scan (last match in seq-ascending order wins) for a store that omits it.\n if (this.store.getLatestCheckpointByName) {\n const latest = await this.store.getLatestCheckpointByName(runId, name);\n return latest?.output as TValue | undefined;\n }\n // listCheckpoints is ordered by seq ascending, so the last match is the most recent value.\n let latest: TValue | undefined;\n for (const cp of await this.store.listCheckpoints(runId))\n if (cp.name === name) latest = cp.output as TValue;\n return latest;\n }\n\n /**\n * Register a validator gating `engine.update(runId, name, …)` for runs of `workflow`. The\n * validator runs BEFORE the update is delivered, so a rejection leaves the run untouched. One\n * validator per (workflow, update name); registering again replaces it.\n */\n registerUpdateValidator<TArg>(\n workflow: string,\n name: string,\n validate: UpdateValidator<TArg>,\n ): void {\n this.updateValidators.set(`${workflow}:${name}`, validate as UpdateValidator);\n }\n\n /**\n * Deliver a validated update to the run waiting at `ctx.onUpdate(name)`. Runs the registered\n * validator (if any) first: on rejection returns `{ accepted: false, reason }` without disturbing\n * the run; otherwise delivers `arg` and resumes, returning `{ accepted: true, run }` (`run` is null\n * if nothing was waiting — a too-early or duplicate update).\n */\n async update(runId: string, name: string, arg: unknown): Promise<UpdateResult> {\n const run = await this.store.getRun(runId);\n if (!run) return { accepted: false, reason: `run ${runId} not found` };\n const validate = this.updateValidators.get(`${run.workflow}:${name}`);\n if (validate) {\n try {\n const reason = await validate(arg);\n if (typeof reason === 'string' && reason.length > 0) return { accepted: false, reason };\n } catch (err) {\n return { accepted: false, reason: err instanceof Error ? err.message : String(err) };\n }\n }\n const result = await this.signal(`update:${runId}:${name}`, arg);\n return { accepted: true, run: result };\n }\n\n private async callRemote<TInput, TOutput>(\n runId: string,\n seq: number,\n step: RemoteStepDef<TInput, TOutput>,\n input: TInput,\n queue?: string,\n transport?: string,\n replay?: Map<number, StepCheckpoint>,\n admission?: { priority?: number | undefined; fairnessKey?: string | undefined },\n ): Promise<TOutput> {\n // Read the prefix from the per-execution snapshot (avoids the O(N²) replay SELECTs); a seq absent\n // from the snapshot — not yet dispatched, or written after the snapshot — falls back to the store.\n const existing = replay?.get(seq) ?? (await this.store.getCheckpoint(runId, seq));\n if (existing && existing.name !== step.name) {\n throw new NonDeterminismError(runId, seq, step.name, existing.name);\n }\n if (existing?.status === 'completed') return existing.output as TOutput;\n if (this.pool.size === 0) throw new Error('remote steps require a Transport');\n // A step with a liveness `timeoutMs` keeps the in-memory await + heartbeat path (re-dispatch a\n // presumed-dead worker). Without one, the call SUSPENDS DURABLY: dispatch, persist a `pending`\n // checkpoint, and let the result resume the run on whichever instance receives it — so a worker\n // pod can scale down or crash mid-step without losing the run or re-running completed work.\n if (step.timeoutMs) return this.callRemoteInMemory(runId, seq, step, input, transport);\n if (existing?.status === 'pending') throw new WorkflowSuspended(); // dispatched; keep waiting\n\n // Durable retry: a failed attempt re-dispatches up to `retries`, spacing attempts by `backoff` —\n // unless the worker marked the error non-retryable (a deterministic verdict like a declined card).\n // The retry deadline is stamped on the failed checkpoint as `wakeAt` (clock-space, persisted) the\n // first time we see it, so it's stable across replays and survives a crash.\n let attempt = 1;\n if (existing?.status === 'failed') {\n const maxAttempts = Math.max(1, step.retries ?? 1);\n const retryable = existing.error?.retryable !== false;\n if (!retryable || existing.attempts >= maxAttempts) throw new RemoteStepError(existing.error);\n if (existing.wakeAt == null) {\n const wakeAt = this.clock() + backoffDelay(existing.attempts, step);\n await this.store.saveCheckpoint({ ...existing, wakeAt });\n throw new WorkflowSuspended(wakeAt);\n }\n if (this.clock() < existing.wakeAt) throw new WorkflowSuspended(existing.wakeAt);\n attempt = existing.attempts + 1;\n }\n\n const id = stepId(runId, seq);\n // Flow control: a queued call that can't be admitted (concurrency/rate) does NOT dispatch — the\n // run re-suspends with the queue's retry time and the timer poller re-tries admission later, so\n // the limit is durable. The admitted slot is released when the result lands (completeRemoteResult).\n if (queue && this.admission.handles(queue)) {\n // Admission carries the per-call priority + fairness key (default the runId so each run is its\n // own fairness bucket), and the stepId as a STABLE waiter id so the backend tracks one waiter\n // across this call's durable retries. Ordering lives in the backend (in-process by default, or\n // global) — this is the dispatch/admission layer, not the positional replay path.\n const decision = await this.admission.tryAdmit(queue, {\n priority: admission?.priority,\n key: admission?.fairnessKey ?? runId,\n waiterId: id,\n });\n if (!decision.ok) {\n // Remember this run as blocked on `queue` so a freed-slot signal can wake it early.\n const waiters = this.queueWaiters.get(queue) ?? new Set<string>();\n waiters.add(runId);\n this.queueWaiters.set(queue, waiters);\n throw new WorkflowSuspended(decision.retryAt);\n }\n this.queueWaiters.get(queue)?.delete(runId);\n this.stepQueue.set(id, queue);\n }\n\n const validInput = step.input.parse(input);\n const enqueuedAt = new Date();\n // Persist the pending checkpoint BEFORE dispatching, so a fast result always finds it to complete.\n await this.store.saveCheckpoint({\n runId,\n seq,\n name: step.name,\n kind: 'remote',\n stepId: id,\n status: 'pending',\n input: validInput,\n attempts: attempt,\n workerGroup: step.group,\n enqueuedAt,\n startedAt: enqueuedAt, // placeholders until the worker result lands\n finishedAt: enqueuedAt,\n });\n await this.pool.dispatch(\n {\n runId,\n seq,\n name: step.name,\n stepId: id,\n group: step.group,\n input: validInput,\n traceparent: this.traceparent?.(),\n context: this.context?.(),\n priority: admission?.priority,\n attempt,\n },\n transport,\n );\n this.emit({ type: 'step.started', runId, seq, name: step.name, kind: 'remote' });\n throw new WorkflowSuspended();\n }\n\n /**\n * Complete a durable remote step from its worker result and resume the run — runs on whichever\n * instance receives the result (the dispatching one may be gone), so the run is crash/scale-safe.\n * A no-op if the checkpoint isn't `pending` (a duplicate or late delivery).\n */\n private async completeRemoteResult(result: StepResult): Promise<void> {\n const cp = await this.store.getCheckpoint(result.runId, result.seq);\n if (!cp || cp.status !== 'pending') return;\n // A result settling this step frees its flow-control slot (no-op if it wasn't queued). Done\n // before the cancelled-run early-return below, so a cancellation can't leak the slot. Released\n // fire-and-forget: the slot/notify is best-effort (a global backend self-heals via lease), and\n // not awaiting keeps it off the result-processing critical path (no ordering shift).\n void this.releaseQueueSlot(cp.stepId).catch(() => undefined);\n // Drop a late result for a run that was cancelled/finished meanwhile — don't complete the step\n // or resume (the run is already terminal). This is the engine side of cooperative cancellation.\n const run = await this.store.getRun(result.runId);\n if (run && (run.status === 'cancelled' || run.status === 'completed')) return;\n const finishedAt = new Date();\n const startedAt = result.startedAt ? new Date(result.startedAt) : cp.startedAt;\n await this.store.saveCheckpoint({\n ...cp,\n status: result.status,\n output: result.status === 'completed' ? result.output : cp.output,\n error: result.error,\n events: result.events ?? cp.events,\n startedAt,\n finishedAt,\n });\n this.emit({\n type: result.status === 'completed' ? 'step.completed' : 'step.failed',\n runId: result.runId,\n seq: result.seq,\n name: cp.name,\n kind: cp.kind,\n output: result.output,\n error: result.error,\n queueMs: startedAt.getTime() - cp.enqueuedAt.getTime(),\n durationMs: finishedAt.getTime() - startedAt.getTime(),\n });\n await this.resume(result.runId);\n }\n\n /**\n * A slot freed on `queue` (a fleet-wide signal): resume this instance's runs blocked on it so they\n * re-contend now instead of at their retry tick. Snapshot-and-clear — a run still blocked after the\n * retry re-registers itself, and one that's gone (cancelled/admitted) is dropped. Best-effort.\n */\n private wakeQueueWaiters(queue: string): void {\n const waiters = this.queueWaiters.get(queue);\n if (!waiters || waiters.size === 0) return;\n const runIds = [...waiters];\n waiters.clear();\n for (const runId of runIds) void this.resume(runId).catch(() => undefined);\n }\n\n /** Release the flow-control slot a dispatched step held (if any), by its stepId. */\n private async releaseQueueSlot(id: string): Promise<void> {\n const queue = this.stepQueue.get(id);\n if (queue === undefined) return;\n this.stepQueue.delete(id);\n await this.admission.release(queue, id);\n }\n\n /** In-memory await path for a remote step with a liveness `timeoutMs` (re-dispatch on timeout). */\n private async callRemoteInMemory<TInput, TOutput>(\n runId: string,\n seq: number,\n step: RemoteStepDef<TInput, TOutput>,\n input: TInput,\n transport?: string,\n ): Promise<TOutput> {\n if (this.pool.size === 0) throw new Error('remote steps require a Transport');\n const validInput = step.input.parse(input);\n const id = stepId(runId, seq);\n const enqueuedAt = new Date();\n this.emit({ type: 'step.started', runId, seq, name: step.name, kind: 'remote' });\n // Retry policy differs from a LOCAL step on purpose: a local `ctx.step` retries any non-fatal\n // throw (the work is in-process), but a remote step only re-dispatches on a liveness TIMEOUT\n // (presumed-dead worker). A worker that *reported* an error returned a deterministic verdict, so\n // we surface it to the workflow instead of hammering the worker. Timeout retries need a window\n // to detect death, so they're gated on `timeoutMs` being set.\n const maxAttempts = step.timeoutMs ? Math.max(1, step.retries ?? 1) : 1;\n\n for (let attempt = 1; ; attempt += 1) {\n const resultPromise = new Promise<RemoteResolution>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n });\n await this.pool.dispatch(\n {\n runId,\n seq,\n name: step.name,\n stepId: id,\n group: step.group,\n input: validInput,\n traceparent: this.traceparent?.(),\n context: this.context?.(),\n attempt,\n },\n transport,\n );\n try {\n const resolution = step.timeoutMs\n ? await this.awaitWithHeartbeat(id, resultPromise, step.timeoutMs)\n : await resultPromise;\n const output = step.output.parse(resolution.output) as TOutput;\n // The worker reports when it actually picked the task up; fall back to dispatch time if a\n // transport doesn't carry it (queue-wait then reads as zero rather than going negative).\n const startedAt = resolution.startedAt ? new Date(resolution.startedAt) : enqueuedAt;\n await this.completeStep({\n runId,\n seq,\n name: step.name,\n kind: 'remote',\n input: validInput,\n output,\n events: resolution.events,\n attempts: attempt,\n workerGroup: step.group,\n enqueuedAt,\n startedAt,\n });\n return output;\n } catch (err) {\n this.pending.delete(id);\n if (err instanceof RemoteStepTimeout && attempt < maxAttempts) continue;\n throw err;\n }\n }\n }\n\n /**\n * Await a remote result, but reject with `RemoteStepTimeout` if neither the result nor a heartbeat\n * arrives within `timeoutMs`. Each heartbeat (delivered via `transport.onHeartbeat`) rearms the\n * window, so a worker that keeps beating stays alive past `timeoutMs`.\n */\n private awaitWithHeartbeat(\n id: string,\n resultPromise: Promise<RemoteResolution>,\n timeoutMs: number,\n ): Promise<RemoteResolution> {\n return new Promise<RemoteResolution>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout>;\n const cleanup = () => {\n clearTimeout(timer);\n this.heartbeatResets.delete(id);\n };\n const arm = () => {\n timer = setTimeout(() => {\n cleanup();\n this.pending.delete(id);\n reject(new RemoteStepTimeout(id, timeoutMs));\n }, timeoutMs);\n (timer as { unref?: () => void }).unref?.();\n };\n this.heartbeatResets.set(id, () => {\n clearTimeout(timer);\n arm();\n });\n arm();\n resultPromise.then(\n (value) => {\n cleanup();\n resolve(value);\n },\n (err) => {\n cleanup();\n reject(err);\n },\n );\n });\n }\n}\n\n/** Raised inside the workflow when a remote worker reports a step failure. */\nexport class RemoteStepError extends Error {\n readonly stepError?: StepError | undefined;\n constructor(stepError?: StepError) {\n super(stepError?.message ?? 'remote step failed');\n this.name = 'RemoteStepError';\n this.stepError = stepError;\n }\n}\n","import type { z } from 'zod';\nimport type { RemoteStepDef, StepOptions } from './interfaces';\n\nexport interface RemoteStepConfig<TInput, TOutput> extends StepOptions {\n name: string;\n /** Worker group expected to handle this step. Defaults to the `name` prefix before the first dot. */\n group?: string;\n input: z.ZodType<TInput>;\n output: z.ZodType<TOutput>;\n}\n\n/**\n * Defines a typed handle to a step that runs on a remote worker. Call it from a workflow with\n * `ctx.call(step, input)`; a worker registers a handler under the same `name`.\n */\nexport function remoteStep<TInput, TOutput>(\n config: RemoteStepConfig<TInput, TOutput>,\n): RemoteStepDef<TInput, TOutput> {\n return {\n ...config,\n group: config.group ?? config.name.split('.')[0] ?? config.name,\n __remote: true,\n };\n}\n","import type {\n HistoryEvent,\n Transport,\n WorkflowDecision,\n WorkflowExecutor,\n WorkflowRun,\n WorkflowTask,\n} from './interfaces';\n\nlet taskCounter = 0;\n\n/**\n * A {@link WorkflowExecutor} backed by a {@link Transport}: it advances a remote workflow by\n * dispatching a {@link WorkflowTask} over the broker and awaiting the matching {@link WorkflowDecision}\n * (correlated by `taskId`). Pass one to `engine.registerRemote(name, version, { group, executor })` so\n * a workflow authored in another SDK (e.g. the Python `durable-worker`) is driven over Redis/BullMQ.\n *\n * Recovery-safe: if the engine crashes awaiting a decision, the re-drive dispatches a fresh task with\n * the same history — the worker's replay is deterministic, so it returns the same decision; a late\n * decision for the old `taskId` simply finds no waiter and is dropped.\n */\nexport class RemoteWorkflowExecutor implements WorkflowExecutor {\n private readonly pending = new Map<string, (decision: WorkflowDecision) => void>();\n private subscribed = false;\n\n constructor(\n private readonly transport: Transport,\n private readonly group: string,\n private readonly opts: { timeoutMs?: number } = {},\n ) {}\n\n private ensureSubscribed(): void {\n if (this.subscribed) return;\n if (!this.transport.onDecision) {\n throw new Error('transport does not support workflow decisions (onDecision)');\n }\n this.subscribed = true;\n this.transport.onDecision(async (decision) => {\n const resolve = this.pending.get(decision.taskId);\n if (resolve) {\n this.pending.delete(decision.taskId);\n resolve(decision);\n }\n });\n }\n\n async advance(run: WorkflowRun, history: HistoryEvent[]): Promise<WorkflowDecision> {\n if (!this.transport.dispatchWorkflowTask) {\n throw new Error('transport does not support workflow tasks (dispatchWorkflowTask)');\n }\n this.ensureSubscribed();\n taskCounter += 1;\n const taskId = `${run.id}:wf:${taskCounter}`;\n const task: WorkflowTask = {\n taskId,\n runId: run.id,\n workflow: run.workflow,\n workflowVersion: run.workflowVersion,\n input: run.input,\n history,\n group: this.group,\n priority: run.priority,\n attempt: 1,\n };\n const decision = new Promise<WorkflowDecision>((resolve, reject) => {\n this.pending.set(taskId, resolve);\n if (this.opts.timeoutMs) {\n const timer = setTimeout(() => {\n this.pending.delete(taskId);\n reject(new Error(`workflow task ${taskId} timed out after ${this.opts.timeoutMs}ms`));\n }, this.opts.timeoutMs);\n (timer as { unref?: () => void }).unref?.();\n }\n });\n await this.transport.dispatchWorkflowTask(task);\n return decision;\n }\n}\n","import type { RunQuery, SignalWaiter, StateStore, StepCheckpoint, WorkflowRun } from './interfaces';\n\n/**\n * Transforms a payload value as it crosses the store boundary — e.g. encrypt-at-rest, compress, or\n * redact PII. `decode` must be the exact inverse of `encode`. Both are synchronous (use a local\n * cipher / codec); wrap an async KMS yourself if you need one.\n */\nexport interface PayloadCodec {\n encode(value: unknown): unknown;\n decode(value: unknown): unknown;\n}\n\n/**\n * A `StateStore` decorator that runs run/step **payloads** (input + output) through a\n * {@link PayloadCodec} — encoded on write, decoded on read — so they're never stored in the clear.\n * Adapter-agnostic: wrap any store. Searchable metadata (id, status, workflow, tags, timestamps) and\n * the structured `error` are left untouched so the dashboard, queries, and recovery still work.\n *\n * ```ts\n * const store = new CodecStateStore(new TypeOrmStateStore(ds), aesCodec);\n * ```\n */\nexport class CodecStateStore implements StateStore {\n constructor(\n private readonly inner: StateStore,\n private readonly codec: PayloadCodec,\n ) {}\n\n private enc(v: unknown): unknown {\n return v === undefined ? undefined : this.codec.encode(v);\n }\n private dec(v: unknown): unknown {\n return v === undefined ? undefined : this.codec.decode(v);\n }\n\n private encRun(run: WorkflowRun): WorkflowRun {\n return { ...run, input: this.enc(run.input), output: this.enc(run.output) };\n }\n private decRun<T extends WorkflowRun | null>(run: T): T {\n return (run && { ...run, input: this.dec(run.input), output: this.dec(run.output) }) as T;\n }\n private encCp(cp: StepCheckpoint): StepCheckpoint {\n return { ...cp, input: this.enc(cp.input), output: this.enc(cp.output) };\n }\n private decCp<T extends StepCheckpoint | null>(cp: T): T {\n return (cp && { ...cp, input: this.dec(cp.input), output: this.dec(cp.output) }) as T;\n }\n\n ensureSchema(): Promise<void> {\n return this.inner.ensureSchema?.() ?? Promise.resolve();\n }\n\n createRun(run: WorkflowRun): Promise<void> {\n return this.inner.createRun(this.encRun(run));\n }\n updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void> {\n const next = { ...patch };\n if ('input' in patch) next.input = this.enc(patch.input);\n if ('output' in patch) next.output = this.enc(patch.output);\n return this.inner.updateRun(runId, next);\n }\n async getRun(runId: string): Promise<WorkflowRun | null> {\n return this.decRun(await this.inner.getRun(runId));\n }\n deleteRun(runId: string): Promise<void> {\n return this.inner.deleteRun(runId);\n }\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n return this.decCp(await this.inner.getCheckpoint(runId, seq));\n }\n saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n return this.inner.saveCheckpoint(this.encCp(checkpoint));\n }\n transaction<T>(\n work: (tx: {\n raw: unknown;\n saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;\n }) => Promise<T>,\n ): Promise<T> {\n if (!this.inner.transaction) {\n throw new Error('the wrapped store does not support transactions');\n }\n // Encode the checkpoint inside the tx, so payloads stay encoded at rest like the normal path.\n return this.inner.transaction((tx) =>\n work({ raw: tx.raw, saveCheckpoint: (cp) => tx.saveCheckpoint(this.encCp(cp)) }),\n );\n }\n async listIncompleteRuns(): Promise<WorkflowRun[]> {\n return (await this.inner.listIncompleteRuns()).map((r) => this.decRun(r));\n }\n async listPendingRuns(limit: number): Promise<WorkflowRun[]> {\n return (await this.inner.listPendingRuns(limit)).map((r) => this.decRun(r));\n }\n async listDueTimers(nowMs: number): Promise<WorkflowRun[]> {\n return (await this.inner.listDueTimers(nowMs)).map((r) => this.decRun(r));\n }\n tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean> {\n return this.inner.tryLockRun(runId, owner, leaseUntilMs, nowMs);\n }\n releaseRunLock(runId: string): Promise<void> {\n return this.inner.releaseRunLock(runId);\n }\n renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n return this.inner.renewRunLock(runId, owner, leaseUntilMs);\n }\n putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n return this.inner.putSignalWaiter(waiter);\n }\n takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n return this.inner.takeSignalWaiter(token);\n }\n listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n return this.inner.listSignalWaiters(prefix);\n }\n bufferSignal(token: string, payload: unknown): Promise<void> {\n return this.inner.bufferSignal(token, this.enc(payload));\n }\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n const buffered = await this.inner.takeBufferedSignal(token);\n return buffered && { payload: this.dec(buffered.payload) };\n }\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n return (await this.inner.listRuns(query)).map((r) => this.decRun(r));\n }\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n return (await this.inner.listCheckpoints(runId)).map((c) => this.decCp(c));\n }\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n // Forward the targeted read when the inner store implements it; otherwise fall back to the\n // (always-present) listCheckpoints scan so wrapping a legacy custom store keeps working.\n if (this.inner.getLatestCheckpointByName) {\n const cp = await this.inner.getLatestCheckpointByName(runId, name);\n return cp ? this.decCp(cp) : undefined;\n }\n let latest: StepCheckpoint | undefined;\n for (const cp of await this.inner.listCheckpoints(runId)) if (cp.name === name) latest = cp;\n return latest ? this.decCp(latest) : undefined;\n }\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n const matches = this.inner.listCheckpointsByNamePrefix\n ? await this.inner.listCheckpointsByNamePrefix(runId, prefixes)\n : (await this.inner.listCheckpoints(runId)).filter((cp) =>\n prefixes.some((p) => cp.name.startsWith(p)),\n );\n return matches.map((c) => this.decCp(c));\n }\n}\n","import type { EngineEvent } from './interfaces';\n\nexport interface MetricsSnapshot {\n runs: { started: number; completed: number; failed: number; suspended: number };\n steps: { started: number; completed: number; failed: number };\n /** Per-workflow run counters, keyed by workflow name. */\n byWorkflow: Record<string, { started: number; completed: number; failed: number }>;\n /** Sum + count of recorded step durations (ms), for an average. */\n stepDuration: { sumMs: number; count: number };\n}\n\nexport interface MetricsCollector {\n snapshot(): MetricsSnapshot;\n /** Prometheus text exposition of the counters — serve this from a `/metrics` endpoint. */\n prometheus(): string;\n /** Unsubscribe from the engine. */\n stop(): void;\n}\n\ntype Subscribable = { subscribe(listener: (event: EngineEvent) => void): () => void };\n\n/**\n * Subscribe to an engine's lifecycle events and accumulate Prometheus-style counters (runs + steps by\n * outcome, per-workflow run counts, step-duration sum/count). Dependency-free — call `.prometheus()`\n * from your metrics endpoint, or `.snapshot()` for the raw numbers. Counters are per process; scrape\n * each instance.\n */\nexport function collectMetrics(engine: Subscribable): MetricsCollector {\n const m: MetricsSnapshot = {\n runs: { started: 0, completed: 0, failed: 0, suspended: 0 },\n steps: { started: 0, completed: 0, failed: 0 },\n byWorkflow: {},\n stepDuration: { sumMs: 0, count: 0 },\n };\n const wf = (name?: string) => {\n const k = name ?? 'unknown';\n let entry = m.byWorkflow[k];\n if (!entry) {\n entry = { started: 0, completed: 0, failed: 0 };\n m.byWorkflow[k] = entry;\n }\n return entry;\n };\n\n const stop = engine.subscribe((e) => {\n switch (e.type) {\n case 'run.started':\n m.runs.started += 1;\n wf(e.workflow).started += 1;\n break;\n case 'run.completed':\n m.runs.completed += 1;\n wf(e.workflow).completed += 1;\n break;\n case 'run.failed':\n m.runs.failed += 1;\n wf(e.workflow).failed += 1;\n break;\n case 'run.suspended':\n m.runs.suspended += 1;\n break;\n case 'step.started':\n m.steps.started += 1;\n break;\n case 'step.completed':\n m.steps.completed += 1;\n if (e.durationMs != null) {\n m.stepDuration.sumMs += e.durationMs;\n m.stepDuration.count += 1;\n }\n break;\n case 'step.failed':\n m.steps.failed += 1;\n break;\n }\n });\n\n return {\n snapshot: () => structuredClone(m),\n stop,\n prometheus: () => {\n const lines: string[] = [];\n lines.push('# TYPE durable_runs_total counter');\n for (const [k, v] of Object.entries(m.runs))\n lines.push(`durable_runs_total{event=\"${k}\"} ${v}`);\n lines.push('# TYPE durable_steps_total counter');\n for (const [k, v] of Object.entries(m.steps))\n lines.push(`durable_steps_total{event=\"${k}\"} ${v}`);\n lines.push('# TYPE durable_runs_by_workflow_total counter');\n for (const [name, v] of Object.entries(m.byWorkflow))\n for (const [event, n] of Object.entries(v))\n lines.push(`durable_runs_by_workflow_total{workflow=\"${name}\",event=\"${event}\"} ${n}`);\n lines.push('# TYPE durable_step_duration_ms_sum counter');\n lines.push(`durable_step_duration_ms_sum ${m.stepDuration.sumMs}`);\n lines.push('# TYPE durable_step_duration_count counter');\n lines.push(`durable_step_duration_count ${m.stepDuration.count}`);\n return `${lines.join('\\n')}\\n`;\n },\n };\n}\n","import { createRequire } from 'node:module';\nimport type { WorkflowEngine } from './engine';\n\n// Resolve the optional `cron-parser` peer dependency in a way that works in BOTH the ESM and CJS\n// builds of this package (dual publish). `createRequire(import.meta.url)` gives a real `require` in\n// ESM output; in the CJS build, tsup's banner shims `import.meta.url` to the file URL, so the same\n// call resolves there too. This keeps the load synchronous (no async leak into the scheduler API).\nconst nodeRequire = createRequire(import.meta.url);\n\nexport interface ScheduledWorkflow {\n /** Stable key identifying this schedule — part of the deterministic run id. */\n key: string;\n workflow: string;\n input?: unknown;\n /** Start one run every `everyMs`. Mutually exclusive with `cron`. */\n everyMs?: number;\n /**\n * A cron expression (5 fields `m h dom mon dow`, or 6 with leading seconds) evaluated in\n * {@link ScheduledWorkflow.timezone}. Mutually exclusive with `everyMs`. Needs the optional peer\n * dependency `cron-parser`.\n */\n cron?: string;\n /** IANA timezone the `cron` fires in (e.g. `America/Sao_Paulo`). Defaults to UTC. */\n timezone?: string;\n /** Temporarily stop firing this schedule (kept registered). Defaults to false. */\n paused?: boolean;\n /**\n * What to do when the previous window's run hasn't finished yet (fixed-interval schedules only):\n * `'allow'` (default) starts the new window anyway; `'skip'` skips it while the prior run is still\n * `running`/`suspended`, so a slow run can't pile up overlapping executions.\n */\n overlap?: 'allow' | 'skip';\n /**\n * Randomly delay the dispatch by up to this many ms BEFORE firing, to spread load when many\n * instances tick on the same boundary (avoids a thundering herd). Opt-in; absent = fire immediately.\n *\n * This is dispatch-path jitter only — it does NOT affect the run id (still the time bucket), so\n * idempotency is unchanged: two instances jittering the same window still start it exactly once.\n * (The engine forbids `Math.random` inside workflow code; the scheduler dispatch path is not\n * workflow code, so jitter here is fine.)\n */\n jitter?: number;\n /**\n * Enqueue windows that were missed while the scheduler was down, instead of silently skipping\n * them. Opt-in; absent = only the current window fires. `maxCatchup` bounds how many PRIOR windows\n * are backfilled (a long outage can't flood the system). Backfilled runs use each missed window's\n * deterministic bucket run id, so `engine.start` idempotency skips any that already ran.\n */\n backfill?: { maxCatchup: number };\n}\n\n/** Injectable dispatch-path effects (kept out of the deterministic run-id logic). Defaults to real\n * `Math.random` + `setTimeout`; overridden in tests so jitter is deterministic and instant. */\nexport interface RunSchedulesOptions {\n random?: () => number;\n sleep?: (ms: number) => Promise<void>;\n}\n\nconst defaultSleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\n/** Deterministic run id for a fixed-interval schedule's current time window. */\nexport function scheduledRunId(key: string, everyMs: number, nowMs: number): string {\n return `sched:${key}:${Math.floor(nowMs / everyMs)}`;\n}\n\ntype CronParser = typeof import('cron-parser');\nlet cronParser: CronParser | undefined;\nfunction loadCronParser(): CronParser {\n if (cronParser) return cronParser;\n try {\n // Lazy + optional: core stays dependency-free; only users who schedule by cron need this.\n cronParser = nodeRequire('cron-parser') as CronParser;\n } catch {\n throw new Error(\n 'cron schedules need the optional peer dependency \"cron-parser\" — install it (e.g. `npm i cron-parser`).',\n );\n }\n return cronParser;\n}\n\n/**\n * Epoch ms of the most recent cron fire at or before `nowMs`, evaluated in `timezone` (default UTC).\n * This is the deterministic \"bucket\" a cron run is keyed on, so polling repeatedly within an\n * interval resolves to the same fire time — and thus the same idempotent run id.\n */\nexport function prevCronFireMs(expr: string, nowMs: number, timezone = 'UTC'): number {\n const parser = loadCronParser();\n // `+1` makes a fire landing exactly on `nowMs` count as \"at or before now\", not the prior one.\n const it = parser.parseExpression(expr, { currentDate: new Date(nowMs + 1), tz: timezone });\n return it.prev().toDate().getTime();\n}\n\n/** The deterministic, idempotent run id for a schedule at `nowMs` — its current fire window. */\nfunction scheduleRunIdAt(s: ScheduledWorkflow, nowMs: number): string {\n if (s.cron != null) return `sched:${s.key}:${prevCronFireMs(s.cron, nowMs, s.timezone)}`;\n if (s.everyMs != null) return scheduledRunId(s.key, s.everyMs, nowMs);\n throw new Error(`schedule \"${s.key}\" needs either \"everyMs\" or \"cron\"`);\n}\n\n/**\n * The run ids this schedule should fire at `nowMs`: the current window, plus — when `backfill` is set\n * — up to `maxCatchup` prior windows that may have been missed. Oldest-first, so a backfill catches\n * up in chronological order. Ids are the same deterministic buckets `scheduleRunIdAt` produces, so\n * `engine.start` idempotency drops any window that already ran.\n */\nfunction scheduleRunIdsAt(s: ScheduledWorkflow, nowMs: number): string[] {\n const current = scheduleRunIdAt(s, nowMs);\n if (!s.backfill || s.backfill.maxCatchup <= 0) return [current];\n\n const ids: string[] = [];\n if (s.everyMs != null) {\n const bucket = Math.floor(nowMs / s.everyMs);\n const oldest = Math.max(0, bucket - s.backfill.maxCatchup);\n for (let b = oldest; b < bucket; b += 1) ids.push(`sched:${s.key}:${b}`);\n } else if (s.cron != null) {\n // Walk back through prior cron fire times (most-recent missed first), then reverse to oldest-first.\n const prior: string[] = [];\n let cursor = prevCronFireMs(s.cron, nowMs, s.timezone);\n for (let i = 0; i < s.backfill.maxCatchup; i += 1) {\n // `cursor` (exclusive) → the fire strictly before it.\n const before = prevCronFireMs(s.cron, cursor - 1, s.timezone);\n prior.push(`sched:${s.key}:${before}`);\n cursor = before;\n }\n ids.push(...prior.reverse());\n }\n ids.push(current);\n return ids;\n}\n\n/**\n * Start each schedule's current-window run. The run id is the time bucket (a fixed-interval index,\n * or the cron fire time) and `engine.start` is idempotent, so firing this on an interval — or\n * racing two instances on the same tick — starts **each window exactly once**. Wire it to a\n * `setInterval`, the durable timer poller, or `@nestjs/schedule`. Returns the run ids for the\n * current windows.\n */\nexport async function runSchedules(\n engine: Pick<WorkflowEngine, 'start' | 'getRun'>,\n schedules: readonly ScheduledWorkflow[],\n nowMs: number,\n opts?: RunSchedulesOptions,\n): Promise<string[]> {\n const random = opts?.random ?? Math.random;\n const sleep = opts?.sleep ?? defaultSleep;\n const ids: string[] = [];\n for (const s of schedules) {\n if (s.paused) continue;\n // overlap:'skip' (fixed-interval): don't start this window while the previous window's run is\n // still in-flight, so a slow run can't pile up. Interval-only — cron windows aren't adjacent ids.\n if (s.overlap === 'skip' && s.everyMs) {\n const prevBucket = Math.floor(nowMs / s.everyMs) - 1;\n if (prevBucket >= 0) {\n const prev = await engine.getRun(`sched:${s.key}:${prevBucket}`);\n if (prev && (prev.status === 'running' || prev.status === 'suspended')) continue;\n }\n }\n // Dispatch-path jitter (not workflow code): spread same-boundary ticks across instances. Applied\n // once per schedule, before firing — the run ids below are unaffected, so idempotency holds.\n if (s.jitter && s.jitter > 0) await sleep(Math.floor(random() * s.jitter));\n for (const runId of scheduleRunIdsAt(s, nowMs)) {\n await engine.start(s.workflow, s.input, runId);\n ids.push(runId);\n }\n }\n return ids;\n}\n","import type { AttributeFilter, AttributeOp, RunQuery, WorkflowRun } from './interfaces';\nimport type { SearchAttributes } from './interfaces';\n\n/** Compare one attribute value against a filter operand. Range ops need both sides comparable. */\nfunction compare(actual: unknown, op: AttributeOp, expected: string | number | boolean): boolean {\n switch (op) {\n case 'eq':\n return actual === expected;\n case 'ne':\n return actual !== expected;\n case 'gt':\n return actual != null && actual > expected;\n case 'gte':\n return actual != null && actual >= expected;\n case 'lt':\n return actual != null && actual < expected;\n case 'lte':\n return actual != null && actual <= expected;\n }\n}\n\n/**\n * Does a run's search attributes satisfy EVERY filter (AND)? A missing key never matches (so `ne`\n * on an absent key is false too — the attribute simply isn't there to compare). Empty/undefined\n * filters match everything. Shared by every store so typed/range queries behave identically across\n * adapters (applied in-process after the coarse workflow/status/tag filters).\n */\nexport function matchesAttributes(\n attributes: SearchAttributes | undefined,\n filters: AttributeFilter[] | undefined,\n): boolean {\n if (!filters?.length) return true;\n if (!attributes) return false;\n return filters.every((f) => f.key in attributes && compare(attributes[f.key], f.op, f.value));\n}\n\n/**\n * Apply a query's attribute predicates then its `offset`/`limit`, in-process — for store adapters\n * that can't express typed/range predicates in SQL. Pass rows already coarse-filtered (workflow /\n * status / tag) and sorted newest-first; this filters by `attributes` and paginates. Only call it\n * when `query.attributes` is set (otherwise let the DB do `LIMIT`/`OFFSET`).\n */\nexport function applyAttributeQuery(rows: WorkflowRun[], query: RunQuery): WorkflowRun[] {\n const filtered = rows.filter((r) => matchesAttributes(r.searchAttributes, query.attributes));\n const offset = query.offset ?? 0;\n const limit = query.limit ?? filtered.length;\n return filtered.slice(offset, offset + limit);\n}\n\n/**\n * One normalized row of the `durable_run_attributes` side-table: a single (key → value) pair of a\n * run's search attributes, split into typed columns so SQL can index/range-scan it. Exactly one of\n * `strValue`/`numValue` is set per row (booleans normalize to a string `\"true\"`/`\"false\"` so `eq`/`ne`\n * still match). NULL for the column that doesn't apply, which keeps `(key, numValue)` /\n * `(key, strValue)` indexes selective.\n */\nexport interface RunAttributeRow {\n runId: string;\n key: string;\n strValue: string | null;\n numValue: number | null;\n}\n\n/**\n * Explode a run's search attributes into normalized side-table rows (one per key). Used by SQL stores\n * to maintain `durable_run_attributes` on every create/update and by the in-memory store's index, so\n * attribute predicates can be pushed DOWN into a join/EXISTS instead of scanned in-process. Numbers go\n * to `numValue`; strings to `strValue`; booleans to `strValue` as `\"true\"`/`\"false\"` (matching how the\n * in-process `compare` treats `eq`/`ne` on booleans). Returns `[]` for a run with no attributes.\n */\nexport function normalizeAttributeRows(\n runId: string,\n attributes: SearchAttributes | undefined,\n): RunAttributeRow[] {\n if (!attributes) return [];\n const out: RunAttributeRow[] = [];\n for (const [key, value] of Object.entries(attributes)) {\n if (typeof value === 'number') {\n out.push({ runId, key, strValue: null, numValue: value });\n } else if (typeof value === 'boolean') {\n out.push({ runId, key, strValue: value ? 'true' : 'false', numValue: null });\n } else {\n out.push({ runId, key, strValue: value, numValue: null });\n }\n }\n return out;\n}\n\n/** SQL comparison operator for an {@link AttributeOp} (used to build pushdown predicates). */\nexport function sqlComparator(op: AttributeOp): string {\n switch (op) {\n case 'eq':\n return '=';\n case 'ne':\n return '<>';\n case 'gt':\n return '>';\n case 'gte':\n return '>=';\n case 'lt':\n return '<';\n case 'lte':\n return '<=';\n }\n}\n\n/**\n * Which side-table column an attribute filter compares against: numeric operands (and range ops on\n * numbers) hit `numValue`; everything else hits `strValue` (booleans are stored as `\"true\"`/`\"false\"`).\n * Keeping this in core means every SQL adapter pushes predicates down identically.\n */\nexport function attributeColumnFor(filter: AttributeFilter): 'numValue' | 'strValue' {\n return typeof filter.value === 'number' ? 'numValue' : 'strValue';\n}\n\n/** The literal a side-table predicate compares against (booleans → `\"true\"`/`\"false\"` strings). */\nexport function attributeOperand(filter: AttributeFilter): string | number {\n if (typeof filter.value === 'boolean') return filter.value ? 'true' : 'false';\n return filter.value;\n}\n","/**\n * Dependency-injection tokens. Adapters bind their implementations to these so `core` and\n * `@dudousxd/nestjs-durable` depend only on the interfaces in `./interfaces`.\n *\n * These use `Symbol.for(key)` (the global symbol registry), NOT `Symbol(key)`, so the token is the\n * SAME instance no matter how many times `core` is evaluated in a process. A consumer can hold more\n * than one physical copy of `core` at runtime — pnpm peer-dependency multiplexing installs a\n * separate virtual copy per distinct peer set, and the dual ESM/CJS build can be loaded once as\n * `import` (`index.js`) and once as `require` (`index.cjs`). A plain `Symbol()` would mint a\n * DISTINCT token per copy, so `DurableModule` (provider) and `DashboardService` / a store adapter\n * (injector) could resolve different symbols → Nest can't satisfy the dependency\n * (`STATE_STORE is not available in the DurableApiModule context`). A registered symbol collapses\n * them to one. Mirrors the `CONTEXT_ACCESSOR` token in `@dudousxd/nestjs-durable`'s `tokens.ts`.\n */\n\n/**\n * @deprecated Use {@link STATE_STORE_CANONICAL} (`@dudousxd/nestjs-durable:state-store`). The legacy\n * token stays bound as a back-compat alias and still resolves; it will be removed in a future major.\n */\nexport const STATE_STORE = Symbol.for('nestjs-durable:STATE_STORE');\n/**\n * @deprecated Use {@link TRANSPORT_CANONICAL} (`@dudousxd/nestjs-durable:transport`). The legacy\n * token stays bound as a back-compat alias and still resolves; it will be removed in a future major.\n */\nexport const TRANSPORT = Symbol.for('nestjs-durable:TRANSPORT');\n/**\n * @deprecated Use {@link DURABLE_OPTIONS_CANONICAL} (`@dudousxd/nestjs-durable:options`). The legacy\n * token stays bound as a back-compat alias and still resolves; it will be removed in a future major.\n */\nexport const DURABLE_OPTIONS = Symbol.for('nestjs-durable:DURABLE_OPTIONS');\n\n/**\n * Canonical, cross-lib-discoverable aliases of the durable DI tokens, following the ecosystem\n * capability naming `@dudousxd/nestjs-durable:<name>` (identical to `capability('durable', <name>)`).\n * `DurableModule` binds these alongside the legacy tokens (dual-bind), so an external library can\n * resolve durable's store/transport/options by the canonical name without importing durable\n * internals. Bare `Symbol.for` (same cross-copy-stability rationale as the legacy tokens above)\n * keeps `core` free of any `@dudousxd/nestjs-diagnostics` runtime dependency.\n */\nexport const STATE_STORE_CANONICAL = Symbol.for('@dudousxd/nestjs-durable:state-store');\nexport const TRANSPORT_CANONICAL = Symbol.for('@dudousxd/nestjs-durable:transport');\nexport const DURABLE_OPTIONS_CANONICAL = Symbol.for('@dudousxd/nestjs-durable:options');\n","import type {\n RunQuery,\n SignalWaiter,\n StateStore,\n StepCheckpoint,\n WorkflowRun,\n} from '../interfaces';\nimport type { AttributeFilter } from '../interfaces';\nimport { type RunAttributeRow, normalizeAttributeRows } from '../search-attributes';\n\n/**\n * A non-durable, in-process `StateStore` for tests and local development.\n * The shipped `@dudousxd/nestjs-durable-store` package re-exports an equivalent.\n */\nexport class InMemoryStateStore implements StateStore {\n private readonly runs = new Map<string, WorkflowRun>();\n private readonly checkpoints = new Map<string, StepCheckpoint>();\n private readonly signalWaiters = new Map<string, SignalWaiter>();\n\n /**\n * Normalized search-attribute side-table, the in-memory analog of the SQL stores'\n * `durable_run_attributes`: `key -> (runId -> row)`. Maintained on every create/update so an\n * attribute query can be pushed DOWN to a key-indexed candidate set instead of scanning every run\n * and comparing in-process. Mirrors {@link normalizeAttributeRows} so behavior matches the SQL path.\n */\n private readonly attributeIndex = new Map<string, Map<string, RunAttributeRow>>();\n /** Test/observability hook: how many candidate runs the last attribute query's index produced. */\n lastAttributeCandidates = 0;\n /**\n * Test/observability hook: how many checkpoint rows the LAST checkpoint read materialized (the rows\n * actually returned to the caller). `listCheckpoints` returns all rows for the run; the targeted\n * {@link getLatestCheckpointByName} / {@link listCheckpointsByNamePrefix} return only the matches —\n * so this lets the benchmark contrast \"fetch N, scan in JS\" against \"fetch the k that match\".\n */\n lastCheckpointRowsRead = 0;\n\n private key(runId: string, seq: number): string {\n return `${runId}:${seq}`;\n }\n\n /** Drop then re-add a run's normalized attribute rows so the index tracks its current attributes. */\n private reindexAttributes(runId: string, attributes: WorkflowRun['searchAttributes']): void {\n for (const byRun of this.attributeIndex.values()) byRun.delete(runId);\n for (const row of normalizeAttributeRows(runId, attributes)) {\n let byRun = this.attributeIndex.get(row.key);\n if (!byRun) {\n byRun = new Map();\n this.attributeIndex.set(row.key, byRun);\n }\n byRun.set(runId, row);\n }\n }\n\n async createRun(run: WorkflowRun): Promise<void> {\n this.runs.set(run.id, { ...run });\n this.reindexAttributes(run.id, run.searchAttributes);\n }\n\n async updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void> {\n const existing = this.runs.get(runId);\n if (!existing) throw new Error(`run ${runId} not found`);\n const next = { ...existing, ...patch };\n this.runs.set(runId, next);\n if ('searchAttributes' in patch) this.reindexAttributes(runId, next.searchAttributes);\n }\n\n async getRun(runId: string): Promise<WorkflowRun | null> {\n const run = this.runs.get(runId);\n return run ? { ...run } : null;\n }\n\n async deleteRun(runId: string): Promise<void> {\n this.runs.delete(runId);\n for (const [key, cp] of this.checkpoints) {\n if (cp.runId === runId) this.checkpoints.delete(key);\n }\n for (const [token, waiter] of this.signalWaiters) {\n if (waiter.runId === runId) this.signalWaiters.delete(token);\n }\n // Drop the run's normalized attribute rows (reindex with no attributes clears them).\n this.reindexAttributes(runId, undefined);\n }\n\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n const cp = this.checkpoints.get(this.key(runId, seq));\n return cp ? { ...cp } : null;\n }\n\n async saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n this.checkpoints.set(this.key(checkpoint.runId, checkpoint.seq), { ...checkpoint });\n }\n\n async listIncompleteRuns(): Promise<WorkflowRun[]> {\n return [...this.runs.values()].filter((r) => r.status === 'running').map((r) => ({ ...r }));\n }\n\n async listPendingRuns(limit: number): Promise<WorkflowRun[]> {\n return [...this.runs.values()]\n .filter((r) => r.status === 'pending')\n .sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime() || a.id.localeCompare(b.id))\n .slice(0, limit)\n .map((r) => ({ ...r }));\n }\n\n async listDueTimers(nowMs: number): Promise<WorkflowRun[]> {\n return [...this.runs.values()]\n .filter((r) => r.status === 'suspended' && r.wakeAt !== undefined && r.wakeAt <= nowMs)\n .map((r) => ({ ...r }));\n }\n\n async tryLockRun(\n runId: string,\n owner: string,\n leaseUntilMs: number,\n nowMs: number,\n ): Promise<boolean> {\n const run = this.runs.get(runId);\n if (!run) return false;\n if (run.lockedUntil !== undefined && run.lockedUntil > nowMs) return false;\n run.lockedBy = owner;\n run.lockedUntil = leaseUntilMs;\n return true;\n }\n\n async releaseRunLock(runId: string): Promise<void> {\n const run = this.runs.get(runId);\n if (run) {\n run.lockedBy = undefined;\n run.lockedUntil = undefined;\n }\n }\n\n async renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n const run = this.runs.get(runId);\n if (!run || run.lockedBy !== owner) return false;\n run.lockedUntil = leaseUntilMs;\n return true;\n }\n\n async putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n this.signalWaiters.set(waiter.token, { ...waiter });\n }\n\n async takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n const waiter = this.signalWaiters.get(token);\n if (!waiter) return null;\n this.signalWaiters.delete(token);\n return { ...waiter };\n }\n\n async listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n return [...this.signalWaiters.values()]\n .filter((w) => w.token.startsWith(prefix))\n .map((w) => ({ ...w }));\n }\n\n // No real DB transaction (there's no DB) — run the work and save the checkpoint. Exactly-once\n // across a crash needs a SQL store; this keeps `ctx.transaction` usable in tests / local dev.\n async transaction<T>(\n work: (tx: {\n raw: unknown;\n saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;\n }) => Promise<T>,\n ): Promise<T> {\n return work({ raw: this, saveCheckpoint: (cp) => this.saveCheckpoint(cp) });\n }\n\n private readonly bufferedSignals = new Map<string, unknown[]>();\n async bufferSignal(token: string, payload: unknown): Promise<void> {\n const queue = this.bufferedSignals.get(token) ?? [];\n queue.push(payload);\n this.bufferedSignals.set(token, queue);\n }\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n const queue = this.bufferedSignals.get(token);\n if (!queue || queue.length === 0) return null;\n const payload = queue.shift();\n if (queue.length === 0) this.bufferedSignals.delete(token);\n return { payload };\n }\n\n /**\n * Candidate run ids satisfying ONE attribute predicate, served from {@link attributeIndex} — the\n * pushdown step. Numeric predicates scan only `numValue` rows under the key; string/boolean ones\n * scan `strValue` rows. This is the in-memory analog of the SQL EXISTS on `durable_run_attributes`.\n */\n private candidatesForFilter(f: AttributeFilter): Set<string> {\n const byRun = this.attributeIndex.get(f.key);\n const out = new Set<string>();\n if (!byRun) return out;\n const numeric = typeof f.value === 'number';\n const operand = typeof f.value === 'boolean' ? (f.value ? 'true' : 'false') : f.value;\n for (const row of byRun.values()) {\n const actual = numeric ? row.numValue : row.strValue;\n if (actual == null) continue;\n let ok = false;\n switch (f.op) {\n case 'eq':\n ok = actual === operand;\n break;\n case 'ne':\n ok = actual !== operand;\n break;\n case 'gt':\n ok = actual > operand;\n break;\n case 'gte':\n ok = actual >= operand;\n break;\n case 'lt':\n ok = actual < operand;\n break;\n case 'lte':\n ok = actual <= operand;\n break;\n }\n if (ok) out.add(row.runId);\n }\n return out;\n }\n\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n let runs = [...this.runs.values()];\n if (query.workflow) runs = runs.filter((r) => r.workflow === query.workflow);\n if (query.status) runs = runs.filter((r) => r.status === query.status);\n if (query.statuses) runs = runs.filter((r) => query.statuses?.includes(r.status));\n if (query.tag) runs = runs.filter((r) => r.tags?.includes(query.tag as string));\n if (query.attributes?.length) {\n // Pushdown: intersect per-predicate candidate sets from the key-indexed side-table, so we only\n // ever materialize the runs that already satisfy EVERY attribute filter (no full per-run scan).\n let candidates: Set<string> | null = null;\n for (const f of query.attributes) {\n const next = this.candidatesForFilter(f);\n if (candidates == null) {\n candidates = next;\n } else {\n const prev: Set<string> = candidates;\n candidates = new Set([...prev].filter((id) => next.has(id)));\n }\n if (candidates.size === 0) break;\n }\n const ids = candidates ?? new Set<string>();\n this.lastAttributeCandidates = ids.size;\n runs = runs.filter((r) => ids.has(r.id));\n }\n // Newest first (matches the store adapters' `createdAt DESC`) — recent runs on top in the dashboard.\n runs.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n const offset = query.offset ?? 0;\n const limit = query.limit ?? runs.length;\n return runs.slice(offset, offset + limit).map((r) => ({ ...r }));\n }\n\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n const rows = [...this.checkpoints.values()]\n .filter((cp) => cp.runId === runId)\n .sort((a, b) => a.seq - b.seq)\n .map((cp) => ({ ...cp }));\n this.lastCheckpointRowsRead = rows.length;\n return rows;\n }\n\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n let latest: StepCheckpoint | undefined;\n for (const cp of this.checkpoints.values()) {\n if (cp.runId !== runId || cp.name !== name) continue;\n if (!latest || cp.seq > latest.seq) latest = cp;\n }\n this.lastCheckpointRowsRead = latest ? 1 : 0;\n return latest ? { ...latest } : undefined;\n }\n\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n const rows = [...this.checkpoints.values()]\n .filter((cp) => cp.runId === runId && prefixes.some((p) => cp.name.startsWith(p)))\n .sort((a, b) => a.seq - b.seq)\n .map((cp) => ({ ...cp }));\n this.lastCheckpointRowsRead = rows.length;\n return rows;\n }\n}\n","import type {\n ControlMessage,\n ControlPlane,\n Heartbeat,\n RemoteTask,\n StepResult,\n Transport,\n WorkflowStepEvent,\n} from '../interfaces';\nimport { type StepHandler, runStepHandler } from '../protocol';\n\n/**\n * An in-process `Transport` (and `ControlPlane`) for tests and local development: registered\n * handlers stand in for remote workers, so a whole cross-app workflow runs in a single process,\n * and control messages broadcast locally. Pass the same instance as both `transport` and\n * `controlPlane`.\n */\nexport class InMemoryTransport implements Transport, ControlPlane {\n private readonly handlers = new Map<string, StepHandler>();\n private resultHandler?: (result: StepResult) => Promise<void>;\n private stepEventHandler?: (event: WorkflowStepEvent) => Promise<void>;\n private readonly controlHandlers = new Set<(msg: ControlMessage) => void>();\n\n /** Register a fake worker handler for a step name. */\n handle(name: string, fn: StepHandler): void {\n this.handlers.set(name, fn);\n }\n\n async dispatch(task: RemoteTask): Promise<void> {\n if (!this.resultHandler) throw new Error('no result handler registered');\n const result = await runStepHandler(task, this.handlers.get(task.name));\n // Deliver the result ASYNCHRONOUSLY, not inline: a durable `ctx.call` suspends the run right\n // after dispatch, so the result must land AFTER that unwinds (else the resume re-enters\n // mid-suspend). Real brokers are async; this mirrors them.\n setImmediate(() => void this.resultHandler?.(result));\n }\n\n onResult(handler: (result: StepResult) => Promise<void>): void {\n this.resultHandler = handler;\n }\n\n onHeartbeat(_handler: (beat: Heartbeat) => Promise<void>): void {\n // In-process handlers run synchronously; there is no liveness to track.\n }\n\n /** Workflow step lifecycle: deliver to the engine's handler (async, mirroring a real broker). */\n async dispatchStepEvent(event: WorkflowStepEvent): Promise<void> {\n await this.stepEventHandler?.(event);\n }\n\n onStepEvent(handler: (event: WorkflowStepEvent) => Promise<void>): void {\n this.stepEventHandler = handler;\n }\n\n // Control plane: broadcast to every registered handler (including the publisher's own — the\n // engine dedupes by `from`), mirroring how a real broker echoes a publish to all subscribers.\n async publishControl(msg: ControlMessage): Promise<void> {\n for (const handler of this.controlHandlers) handler(msg);\n }\n\n onControl(handler: (msg: ControlMessage) => void): void {\n this.controlHandlers.add(handler);\n }\n}\n"],"mappings":"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","names":["QueueController","inFlight","windowStart","windowCount","waiters","Map","waiterSeq","keyServed","servedTick","config","clock","ordered","fairness","order","tryAdmit","item","now","rl","rateLimit","periodMs","limit","ok","retryAt","usingOrder","priority","waiterId","full","concurrency","register","retryMs","size","isNext","delete","key","set","release","existing","get","seq","self","undefined","Number","POSITIVE_INFINITY","best","w","values","better","a","b","sa","servedOf","sb","InMemoryAdmissionBackend","controllers","Map","clock","register","config","set","name","QueueController","handles","queue","has","tryAdmit","item","controller","get","ok","release","_slotId","UNIT_MS","ms","s","sec","second","seconds","m","min","minute","minutes","h","hr","hour","hours","d","day","days","w","week","weeks","parseDuration","duration","match","trim","Error","value","Number","unit","toLowerCase","factor","undefined","backoffDelay","attempt","options","base","backoffMs","raw","backoff","capped","backoffMaxMs","Math","min","jitter","round","random","withDuration","start","now","data","base","durationMs","createStepLogger","events","currentSub","push","level","message","at","subId","id","undefined","subEvent","e","status","phase","name","group","subProcess","body","opts","globalThis","crypto","randomUUID","prevSub","terminal","emit","handle","skip","reason","fail","result","err","Error","String","debug","m","d","info","warn","error","sub","stepId","runId","seq","breakpointToken","runStepHandler","task","handler","base","startedAt","Date","now","status","error","message","name","retryable","events","withEvents","result","length","output","input","createStepLogger","err","e","Error","String","code","nonEmptyEvents","events","length","undefined","stepCheckpoint","p","runId","seq","name","kind","stepId","status","input","output","error","attempts","workerGroup","wakeAt","enqueuedAt","startedAt","finishedAt","instantCheckpoint","at","Date","FatalError","Error","code","message","name","SingletonQueueFullError","workflow","key","maxQueueDepth","SignalTimeoutError","token","timeoutMs","RemoteStepTimeout","stepId","NonDeterminismError","runId","seq","expected","recorded","WorkflowSuspended","wakeAt","ContinueAsNew","input","ENTITY_WORKFLOW","entityRunId","name","key","Entities","configs","Map","host","register","ctx","input","run","config","set","dispatch","op","arg","reply","runId","signalWithStart","token","payload","signal","getState","getEvent","get","FatalError","state","initialState","i","msg","waitForSignal","out","step","handler","handlers","result","setEvent","accToken","target","EventAccumulators","host","register","ctx","input","debounce","batch","route","config","payload","workflow","mode","windowMs","maxSize","signalWithStart","token","last","waitForSignal","timeoutMs","e","SignalTimeoutError","startChild","continueAsNew","events","deadline","now","length","remaining","push","enc","s","Buffer","from","toString","dec","eventPrefix","name","eventToken","match","runId","seq","JSON","stringify","eventMatchOf","token","parse","split","eventMatches","payload","keys","Object","length","p","every","k","SINGLETON_RETRY_MS","SINGLETON_RETRY_JITTER_MS","SingletonGate","deps","tag","cfg","input","key","retryWakeAt","clock","Math","floor","random","assertCapacity","workflow","maxQueueDepth","cap","limit","queued","store","listRuns","statuses","length","SingletonQueueFullError","admit","run","inflight","sort","a","b","createdAt","getTime","id","localeCompare","idx","findIndex","r","wakeNext","settled","configFor","tags","find","t","startsWith","gated","next","slice","wakeAt","updateRun","undefined","updatedAt","Date","catch","dispatch","TransportPool","transports","size","length","bind","onResult","onHeartbeat","onStepEvent","transport","dispatch","task","preferId","lastErr","id","ordered","err","Error","groupHealth","group","reports","push","undefined","depth","reduce","sum","r","liveWorkers","flatMap","listWorkerGroups","groups","Set","g","add","pref","filter","t","unwrapCompletion","payload","label","c","ok","FatalError","error","value","WORKFLOW_NAME_KEY","Symbol","for","workflowName","ref","name","Error","normalizeChildOptions","options","childId","Position","seq","next","rewind","createWorkflowCtx","host","runId","compensations","workflow","store","replay","pos","readCheckpoint","hit","get","undefined","getCheckpoint","writeCheckpoint","cp","saveCheckpoint","set","step","name","fn","current","existing","NonDeterminismError","status","compensate","push","output","maxAttempts","Math","max","retries","startedAt","Date","startStep","kind","attempts","enqueuedAt","attempt","events","invocation","stepName","body","createStepLogger","clock","interceptStep","completeStep","err","FatalError","failStep","error","message","Error","String","stack","wait","backoffDelay","Promise","resolve","setTimeout","transaction","tx","raw","instantCheckpoint","suspendUntil","wakeAt","now","WorkflowSuspended","at","sleep","duration","parseDuration","sleepUntil","when","getTime","continueAsNew","input","ContinueAsNew","consumeBuffered","token","buffered","takeBufferedSignal","payload","value","waitForSignal","opts","timeoutMs","putSignalWaiter","deadlineSeq","waitSeq","recorded","deadline","waited","takeSignalWaiter","catch","SignalTimeoutError","waitForEvent","eventToken","match","task","dispatch","unwrapCompletion","child","priority","id","getRun","startChild","workflowName","callEntity","key","op","arg","reply","signalEntity","breakpoint","label","breakpointToken","patched","marker","startsWith","onUpdate","setEvent","webhook","url","webhookUrl","random","uuid","globalThis","crypto","randomUUID","call","remote","callRemote","queue","transport","fairnessKey","mergeTags","staticTags","runTags","length","undefined","Set","BREAKPOINT","isBreakpoint","cp","status","name","startsWith","versionKey","version","nextContinuationId","runId","m","match","Number","isNewerVersion","a","b","na","nb","isNaN","localeCompare","numeric","WorkflowEngine","store","pool","controlPlane","clock","instanceId","leaseMs","maxRecoveryAttempts","webhookUrl","traceparent","context","rehydrate","compensationRetries","trackStepStart","runDispatcher","singletons","workflows","Map","latest","eventTriggers","entities","accumulators","pending","heartbeatResets","listeners","interceptors","cancelListeners","enqueuedListeners","deadListeners","updateValidators","cancelRequested","admission","queueWaiters","stepQueue","inflight","draining","deps","TransportPool","transports","transport","id","Date","now","InMemoryAdmissionBackend","onFreed","queue","wakeQueueWaiters","globalThis","crypto","randomUUID","_carrier","fn","Math","max","dispatch","queueMicrotask","runOne","catch","SingletonGate","configFor","run","get","workflow","workflowVersion","singleton","bind","result","waiter","stepId","delete","resolve","output","startedAt","events","reject","RemoteStepError","error","completeRemoteResult","beat","event","persistStepEvent","onControl","msg","from","kind","deliver","at","notifyCancelled","EventAccumulators","Entities","registerEntity","config","register","signalEntity","key","op","arg","signal","getEntityState","getState","onEnqueued","listener","add","opts","registered","tags","executionTimeoutMs","executionTimeout","parseDuration","validateInput","onEvent","eventBatch","set","current","subscribers","registerRemote","Error","remote","group","executor","registerQueue","subscribe","use","interceptor","push","i","indexOf","splice","interceptStep","invocation","body","carrier","chain","reduceRight","next","onCancel","onDead","notifyDead","emit","full","publishControl","start","input","workflowName","prior","getRun","tag","assertCapacity","searchAttributes","priority","createdAt","updatedAt","createRun","resume","track","execute","p","finally","drain","timeoutMs","size","timer","Promise","t","setTimeout","unref","race","allSettled","sweepTimeouts","reg","values","deadline","listRuns","getTime","message","code","updateRun","type","recoverIncomplete","nowMs","results","listIncompleteRuns","acquired","tryLockRun","settled","countRecovery","releaseRunLock","attempts","recoveryAttempts","resumeDueTimers","resumeLeased","listDueTimers","requeue","retryWithInput","newRunId","slice","runPending","listPendingRuns","waitForRun","isSettled","s","toResult","done","off","finish","clearTimeout","check","then","ev","runs","onLocked","publishEvent","payload","touched","waiters","listSignalWaiters","eventPrefix","w","eventMatches","eventMatchOf","token","eventId","batch","route","takeSignalWaiter","bufferSignal","saveCheckpoint","instantCheckpoint","seq","signalWithStart","completeTask","ok","value","failTask","notifyParent","completion","cancel","compensate","cancelChildren","wakeNext","cancelWhere","filter","r","deleteRun","deleted","childId","getRunChildren","parentRunId","childIds","prefixes","childCheckpoints","listCheckpointsByNamePrefix","listCheckpoints","some","knownGroups","extra","groups","def","workerHealth","listWorkerGroups","out","health","groupHealth","phase","stepCheckpoint","enqueuedAt","finishedAt","failed","startStep","step","workerGroup","completeStep","queueMs","durationMs","failStep","lockNow","lockedBy","lockedUntil","renew","setInterval","renewRunLock","floor","runRemoteExecution","runExecution","clearInterval","settleRun","outcome","wakeAt","admit","retryWakeAt","history","remoteHistory","decision","advance","err","String","stack","applyCommands","commands","checkpoints","kindOf","local","sleep","sort","cmd","attempt","ms","min","buffered","takeBufferedSignal","putSignalWaiter","compensations","snapshot","replay","ctx","createWorkflowCtx","ctxHostFor","ContinueAsNew","nextId","WorkflowSuspended","has","comp","runCompensation","callRemote","startChild","reply","continue","bp","find","breakpointToken","getEvent","getLatestCheckpointByName","registerUpdateValidator","validate","update","accepted","reason","existing","getCheckpoint","NonDeterminismError","callRemoteInMemory","maxAttempts","retries","retryable","backoffDelay","handles","tryAdmit","fairnessKey","waiterId","retryAt","validInput","parse","releaseQueueSlot","runIds","clear","release","resultPromise","resolution","awaitWithHeartbeat","RemoteStepTimeout","cleanup","arm","stepError","remoteStep","config","group","name","split","__remote","taskCounter","RemoteWorkflowExecutor","pending","Map","subscribed","transport","group","opts","ensureSubscribed","onDecision","Error","decision","resolve","get","taskId","delete","advance","run","history","dispatchWorkflowTask","id","task","runId","workflow","workflowVersion","input","priority","attempt","Promise","reject","set","timeoutMs","timer","setTimeout","unref","CodecStateStore","inner","codec","enc","v","undefined","encode","dec","decode","encRun","run","input","output","decRun","encCp","cp","decCp","ensureSchema","Promise","resolve","createRun","updateRun","runId","patch","next","getRun","deleteRun","getCheckpoint","seq","saveCheckpoint","checkpoint","transaction","work","Error","tx","raw","listIncompleteRuns","map","r","listPendingRuns","limit","listDueTimers","nowMs","tryLockRun","owner","leaseUntilMs","releaseRunLock","renewRunLock","putSignalWaiter","waiter","takeSignalWaiter","token","listSignalWaiters","prefix","bufferSignal","payload","takeBufferedSignal","buffered","listRuns","query","listCheckpoints","c","getLatestCheckpointByName","name","latest","listCheckpointsByNamePrefix","prefixes","matches","filter","some","p","startsWith","collectMetrics","engine","m","runs","started","completed","failed","suspended","steps","byWorkflow","stepDuration","sumMs","count","wf","name","k","entry","stop","subscribe","e","type","workflow","durationMs","snapshot","structuredClone","prometheus","lines","push","v","Object","entries","event","n","join","nodeRequire","createRequire","defaultSleep","ms","Promise","r","setTimeout","scheduledRunId","key","everyMs","nowMs","Math","floor","cronParser","loadCronParser","Error","prevCronFireMs","expr","timezone","parser","it","parseExpression","currentDate","Date","tz","prev","toDate","getTime","scheduleRunIdAt","s","cron","scheduleRunIdsAt","current","backfill","maxCatchup","ids","bucket","oldest","max","b","push","prior","cursor","i","before","reverse","runSchedules","engine","schedules","opts","random","sleep","paused","overlap","prevBucket","getRun","status","jitter","runId","start","workflow","input","compare","actual","op","expected","matchesAttributes","attributes","filters","length","every","f","key","value","applyAttributeQuery","rows","query","filtered","filter","r","searchAttributes","offset","limit","slice","normalizeAttributeRows","runId","out","Object","entries","push","strValue","numValue","sqlComparator","attributeColumnFor","attributeOperand","STATE_STORE","Symbol","for","TRANSPORT","DURABLE_OPTIONS","STATE_STORE_CANONICAL","TRANSPORT_CANONICAL","DURABLE_OPTIONS_CANONICAL","InMemoryStateStore","runs","Map","checkpoints","signalWaiters","attributeIndex","lastAttributeCandidates","lastCheckpointRowsRead","key","runId","seq","reindexAttributes","attributes","byRun","values","delete","row","normalizeAttributeRows","get","set","createRun","run","id","searchAttributes","updateRun","patch","existing","Error","next","getRun","deleteRun","cp","token","waiter","undefined","getCheckpoint","saveCheckpoint","checkpoint","listIncompleteRuns","filter","r","status","map","listPendingRuns","limit","sort","a","b","createdAt","getTime","localeCompare","slice","listDueTimers","nowMs","wakeAt","tryLockRun","owner","leaseUntilMs","lockedUntil","lockedBy","releaseRunLock","renewRunLock","putSignalWaiter","takeSignalWaiter","listSignalWaiters","prefix","w","startsWith","transaction","work","raw","bufferedSignals","bufferSignal","payload","queue","push","takeBufferedSignal","length","shift","candidatesForFilter","f","out","Set","numeric","value","operand","actual","numValue","strValue","ok","op","add","listRuns","query","workflow","statuses","includes","tag","tags","candidates","prev","has","size","ids","offset","listCheckpoints","rows","getLatestCheckpointByName","name","latest","listCheckpointsByNamePrefix","prefixes","some","p","InMemoryTransport","handlers","Map","resultHandler","stepEventHandler","controlHandlers","Set","handle","name","fn","set","dispatch","task","Error","result","runStepHandler","get","setImmediate","onResult","handler","onHeartbeat","_handler","dispatchStepEvent","event","onStepEvent","publishControl","msg","onControl","add"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/queue.ts","../src/admission.ts","../src/duration.ts","../src/backoff.ts","../src/step-logger.ts","../src/protocol.ts","../src/checkpoints.ts","../src/errors.ts","../src/entities.ts","../src/event-accumulators.ts","../src/events.ts","../src/singleton-gate.ts","../src/transport-pool.ts","../src/completion.ts","../src/workflow-ref.ts","../src/workflow-ctx.ts","../src/engine.ts","../src/remote-step-factory.ts","../src/remote-workflow-executor.ts","../src/codec-state-store.ts","../src/metrics.ts","../src/scheduler.ts","../src/search-attributes.ts","../src/tokens.ts","../src/testing/in-memory-state-store.ts","../src/testing/in-memory-transport.ts"],"sourcesContent":["export * from './admission';\nexport * from './duration';\nexport * from './engine';\nexport * from './entities';\nexport * from './errors';\nexport * from './event-accumulators';\nexport * from './interfaces';\nexport * from './protocol';\nexport * from './queue';\nexport * from './remote-step-factory';\nexport * from './remote-workflow-executor';\nexport * from './codec-state-store';\nexport * from './events';\nexport * from './metrics';\nexport * from './scheduler';\nexport { createStepLogger } from './step-logger';\nexport * from './search-attributes';\nexport * from './tokens';\nexport * from './workflow-ref';\nexport { InMemoryStateStore } from './testing/in-memory-state-store';\nexport { InMemoryTransport } from './testing/in-memory-transport';\n","/**\n * Flow control for remote steps. A queue caps how much work `ctx.call(step, input, { queue })`\n * admits at once — a concurrency limit and/or a fixed-window rate limit. When a call can't be\n * admitted it doesn't dispatch: the run re-suspends with a near-future wake time, and the timer\n * poller re-tries admission later — so flow control is durable (survives crashes) without holding\n * the run in memory.\n *\n * Accounting is per engine instance (the DBOS `workerConcurrency` tier): correct for the common\n * single-orchestrator deployment. Global, cross-instance limits would need a durable counter in the\n * store — a deliberate follow-up, not built here.\n *\n * Beyond raw caps, the controller can admit contended slots by PRIORITY and by per-KEY FAIRNESS\n * (round-robin), so a single noisy key/tenant can't monopolize the concurrency budget. This is the\n * DISPATCH/admission layer — it never touches workflow replay (engine positional logic). Default\n * behaviour is unchanged FIFO when neither priority nor fairness is configured/passed.\n *\n * Design (vs Temporal/Inngest/DBOS): Temporal task queues are FIFO with separate priority levels;\n * Inngest concurrency keys + throttle give per-key fairness; DBOS queues are FIFO with a\n * `workerConcurrency` cap. We fold both knobs into the same in-process admission gate: an optional\n * per-call `priority` (higher first) and an optional queue-level `fairness: 'key'` (round-robin by\n * the per-call `key`). Because blocked calls re-suspend durably and retry independently (there is no\n * resident FIFO list to reorder), the controller remembers the set of WAITERS that asked-and-were-\n * blocked, and on a later retry only admits the one that is rightful-next under the policy.\n */\nexport interface QueueConfig {\n /** Queue name, referenced by `ctx.call(step, input, { queue: name })`. */\n name: string;\n /** Max steps in flight at once for this queue (this instance). Omit for unlimited. */\n concurrency?: number;\n /** Fixed-window rate limit: at most `limit` admissions per `periodMs`. Omit for unlimited. */\n rateLimit?: { limit: number; periodMs: number };\n /** Delay (ms) before a concurrency-blocked call re-checks for a free slot. Default 1000. */\n retryMs?: number;\n /**\n * Fairness policy for a contended concurrency slot. `'key'` round-robins across distinct per-call\n * keys (the least-recently-served key wins the next slot), so one key can't monopolize the budget.\n * Omit (or `'fifo'`) for plain first-come ordering. Priority always wins over fairness; fairness\n * only breaks ties within the same priority.\n */\n fairness?: 'fifo' | 'key';\n /**\n * Arrival-order tiebreak among otherwise-equal waiters (same priority, same fairness rank).\n * `'fifo'` (default) admits the earliest arrival; `'lifo'` admits the most recent (a stack). Orthogonal\n * to `priority` and `fairness` — those still win first; this only breaks their ties.\n */\n order?: 'fifo' | 'lifo';\n}\n\n/**\n * Per-call admission hints. All optional — omitting them keeps the legacy FIFO behaviour.\n * - `priority`: higher is admitted first (default 0).\n * - `key`: the fairness bucket (e.g. a tenant id) for `fairness: 'key'`.\n * - `waiterId`: a stable id for THIS call across its retries (the engine passes the stepId), so the\n * controller can track it as one waiter instead of counting each retry as a new contender.\n */\nexport interface AdmissionItem {\n priority?: number | undefined;\n key?: string | undefined;\n waiterId?: string | undefined;\n}\n\n/** Admission decision: either admitted, or blocked until `retryAt` (epoch ms). */\nexport type Admission = { ok: true } | { ok: false; retryAt: number };\n\n/** A call that asked for a slot and was blocked — remembered so the controller can order admission. */\ninterface Waiter {\n priority: number;\n key?: string | undefined;\n /** Monotonic registration order — FIFO tiebreak within equal priority/fairness. */\n seq: number;\n}\n\n/** In-process admission controller for one {@link QueueConfig}. */\nexport class QueueController {\n private inFlight = 0;\n private windowStart = 0;\n private windowCount = 0;\n /** Registered waiters by id (only used when priority/fairness ordering is in play). */\n private readonly waiters = new Map<string, Waiter>();\n /** Monotonic counter stamping each newly-seen waiter for a stable FIFO tiebreak. */\n private waiterSeq = 0;\n /** Per-key \"last served\" order for round-robin fairness — higher = more recently served. */\n private readonly keyServed = new Map<string, number>();\n private servedTick = 0;\n\n constructor(\n readonly config: QueueConfig,\n private readonly clock: () => number,\n ) {}\n\n /** Whether this controller does any priority/fairness ordering (else it's a plain FIFO gate). */\n private get ordered(): boolean {\n return this.config.fairness === 'key' || this.config.order === 'lifo';\n }\n\n /**\n * Try to admit one unit of work. On `ok`, the caller has taken a concurrency slot and must call\n * {@link release} when the step settles. On block, `retryAt` is when admission may next succeed.\n *\n * `item` carries optional priority/fairness hints; omitting it is the legacy FIFO path. When\n * ordering is configured (or a priority is given), a blocked call REGISTERS as a waiter and is only\n * admitted on a later retry once it is the rightful next under (priority desc, fairness, FIFO).\n */\n tryAdmit(item?: AdmissionItem): Admission {\n const now = this.clock();\n const rl = this.config.rateLimit;\n // Rate limit is a hard global window — checked first and unaffected by priority/fairness.\n if (rl) {\n if (now - this.windowStart >= rl.periodMs) {\n this.windowStart = now;\n this.windowCount = 0;\n }\n if (this.windowCount >= rl.limit)\n return { ok: false, retryAt: this.windowStart + rl.periodMs };\n }\n\n const usingOrder = this.ordered || item?.priority != null || item?.waiterId != null;\n const waiterId = item?.waiterId;\n\n // Concurrency gate.\n const full = this.config.concurrency != null && this.inFlight >= this.config.concurrency;\n if (full) {\n // No slot at all → block (and register as a waiter so a later retry can be ordered).\n if (usingOrder && waiterId != null) this.register(waiterId, item);\n return { ok: false, retryAt: now + (this.config.retryMs ?? 1000) };\n }\n\n // A slot is free. Without ordering, admit immediately (legacy FIFO). With ordering, only admit if\n // THIS call is the rightful next among all registered waiters — otherwise keep it waiting so the\n // freed slot can go to a higher-priority / under-served key on its retry.\n if (usingOrder && this.waiters.size > 0) {\n if (waiterId != null) this.register(waiterId, item);\n if (!this.isNext(waiterId, item)) {\n return { ok: false, retryAt: now + (this.config.retryMs ?? 1000) };\n }\n }\n\n // Admit: consume the slot, the rate-window tick, and clear this waiter.\n if (rl) this.windowCount += 1;\n this.inFlight += 1;\n if (waiterId != null) this.waiters.delete(waiterId);\n if (item?.key != null) this.keyServed.set(item.key, ++this.servedTick);\n return { ok: true };\n }\n\n /** Release a concurrency slot taken by a successful {@link tryAdmit}. */\n release(): void {\n if (this.inFlight > 0) this.inFlight -= 1;\n }\n\n /** Track (or refresh) a blocked call as a waiter; its FIFO seq is stamped only on first sight. */\n private register(waiterId: string, item?: AdmissionItem): void {\n const existing = this.waiters.get(waiterId);\n if (existing) {\n existing.priority = item?.priority ?? 0;\n existing.key = item?.key;\n return;\n }\n this.waiters.set(waiterId, {\n priority: item?.priority ?? 0,\n key: item?.key,\n seq: this.waiterSeq++,\n });\n }\n\n /**\n * Is the calling item the best candidate among all registered waiters? Ordering, best first:\n * 1. higher `priority`;\n * 2. fairness: with `fairness: 'key'`, the least-recently-served key wins (round-robin);\n * 3. earliest registration (FIFO) — stable tiebreak.\n * A bare item (no waiterId) is compared on its hints directly.\n */\n private isNext(waiterId: string | undefined, item?: AdmissionItem): boolean {\n const self: Waiter =\n (waiterId != null ? this.waiters.get(waiterId) : undefined) ??\n ({ priority: item?.priority ?? 0, key: item?.key, seq: Number.POSITIVE_INFINITY } as Waiter);\n let best = self;\n for (const w of this.waiters.values()) {\n if (this.better(w, best)) best = w;\n }\n return best === self;\n }\n\n /** Strict \"a should be admitted before b\" comparison under the active policy. */\n private better(a: Waiter, b: Waiter): boolean {\n if (a.priority !== b.priority) return a.priority > b.priority;\n if (this.config.fairness === 'key') {\n const sa = this.servedOf(a.key);\n const sb = this.servedOf(b.key);\n if (sa !== sb) return sa < sb; // least-recently-served key first\n }\n return this.config.order === 'lifo' ? a.seq > b.seq : a.seq < b.seq; // arrival tiebreak\n }\n\n /** Last-served tick for a key (0 = never served, so an unseen key is admitted before a busy one). */\n private servedOf(key?: string): number {\n if (key == null) return 0;\n return this.keyServed.get(key) ?? 0;\n }\n}\n","import { type Admission, type AdmissionItem, type QueueConfig, QueueController } from './queue';\n\n/**\n * Pluggable backend for the remote-step flow-control gate (`ctx.call(step, input, { queue })`). The\n * engine asks it whether a queued call may be admitted now (concurrency / rate / ordering) and tells\n * it when an admitted slot is released.\n *\n * The default {@link InMemoryAdmissionBackend} keeps per-instance counts — correct for a single\n * orchestrator. Swap in a store/Redis-backed backend to make the caps and ordering GLOBAL across\n * engine replicas (so `concurrency: 5` means 5 in-flight across the whole fleet, not 5 per pod).\n *\n * `tryAdmit`/`release` are async so a global backend can do its atomic round-trip; the in-memory one\n * resolves synchronously. An UNREGISTERED queue name is treated as ungated (admits immediately) — the\n * engine only tracks/releases a slot for a registered queue.\n */\nexport interface AdmissionBackend {\n /** Register (or replace) a queue's config. Called from `engine.registerQueue`. */\n register(config: QueueConfig): void;\n /** Whether `queue` is registered (gated). The engine only tracks/releases a slot for a gated queue. */\n handles(queue: string): boolean;\n /** May a call on `queue` take a slot now? On `ok`, the caller holds a slot until {@link release}. */\n tryAdmit(queue: string, item: AdmissionItem): Promise<Admission>;\n /**\n * Release the slot granted by {@link tryAdmit} for `queue`. `slotId` is the admitted item's\n * `waiterId` (the engine's stepId), so a lease-based backend can drop the exact slot; an in-process\n * counter ignores it.\n */\n release(queue: string, slotId: string): Promise<void>;\n /**\n * Optional: subscribe to \"a slot just freed on `queue`\" events (e.g. a fleet-wide pub/sub). The\n * engine uses it to wake its admission-blocked runs early instead of waiting for their retry tick.\n * A backend without it falls back to retry-tick polling. Fired best-effort across the fleet.\n */\n onFreed?(handler: (queue: string) => void): void;\n}\n\n/**\n * Default admission backend: one in-process {@link QueueController} per registered queue. Caps and\n * waiter ordering are per engine instance (see {@link QueueConfig}). Preserves the exact pre-backend\n * behaviour — the engine used to hold these controllers directly.\n */\nexport class InMemoryAdmissionBackend implements AdmissionBackend {\n private readonly controllers = new Map<string, QueueController>();\n\n constructor(private readonly clock: () => number) {}\n\n register(config: QueueConfig): void {\n this.controllers.set(config.name, new QueueController(config, this.clock));\n }\n\n handles(queue: string): boolean {\n return this.controllers.has(queue);\n }\n\n async tryAdmit(queue: string, item: AdmissionItem): Promise<Admission> {\n const controller = this.controllers.get(queue);\n // Unregistered queue → ungated (mirrors the old `this.queues.get(queue)` truthiness check).\n if (!controller) return { ok: true };\n return controller.tryAdmit(item);\n }\n\n async release(queue: string, _slotId: string): Promise<void> {\n this.controllers.get(queue)?.release();\n }\n}\n","const UNIT_MS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n sec: 1_000,\n second: 1_000,\n seconds: 1_000,\n m: 60_000,\n min: 60_000,\n minute: 60_000,\n minutes: 60_000,\n h: 3_600_000,\n hr: 3_600_000,\n hour: 3_600_000,\n hours: 3_600_000,\n d: 86_400_000,\n day: 86_400_000,\n days: 86_400_000,\n w: 604_800_000,\n week: 604_800_000,\n weeks: 604_800_000,\n};\n\n/**\n * Parse a human duration to milliseconds. Accepts a number (already ms) or a string like\n * `'500ms'`, `'30s'`, `'15m'`, `'2h'`, `'7d'`, `'7 days'`.\n */\nexport function parseDuration(duration: string | number): number {\n if (typeof duration === 'number') return duration;\n const match = duration.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*([a-z]+)$/i);\n if (!match) throw new Error(`invalid duration: ${duration}`);\n const value = Number(match[1]);\n const unit = (match[2] ?? '').toLowerCase();\n const factor = UNIT_MS[unit];\n if (factor === undefined) throw new Error(`unknown duration unit: ${unit}`);\n return value * factor;\n}\n","import type { StepOptions } from './interfaces';\n\n/** Delay in ms before the next retry attempt, per a step's `StepOptions` backoff config. Shared by\n * the local-step retry loop and the durable remote-step retry, so they stay consistent. */\nexport function backoffDelay(attempt: number, options?: StepOptions): number {\n const base = options?.backoffMs ?? 0;\n if (base <= 0) return 0;\n const raw = options?.backoff === 'exp' ? base * 2 ** (attempt - 1) : base;\n const capped = options?.backoffMaxMs ? Math.min(raw, options.backoffMaxMs) : raw;\n return options?.jitter ? Math.round(capped * (0.5 + Math.random() * 0.5)) : capped;\n}\n","import type { StepEvent, StepLogger, SubProcessHandle } from './interfaces';\n\n/** Attach the elapsed `durationMs` (from `start`) to `data`, unless the caller already set one. */\nfunction withDuration(start: number, now: () => number, data?: unknown): Record<string, unknown> {\n if (data && typeof data === 'object' && 'durationMs' in data) {\n return data as Record<string, unknown>;\n }\n const base = data && typeof data === 'object' ? (data as Record<string, unknown>) : {};\n return { ...base, durationMs: now() - start };\n}\n\n/**\n * A {@link StepLogger} that appends to `events`, stamping each line with `now()`. Shared by the\n * local-step path (`ctx.step`) and the remote-worker path (`runStepHandler`) so a step records\n * the same {@link StepEvent} shape wherever it runs — the TypeScript twin of the Python SDK's\n * `StepContext`.\n */\nexport function createStepLogger(events: StepEvent[], now: () => number): StepLogger {\n // The sub-process a `subProcess(...)` body is currently inside; debug/info/warn/error emitted while\n // inside get tagged with its id, so the dashboard groups that log trail under the sub-process.\n let currentSub: { id: string } | undefined;\n const push = (level: StepEvent['level'], message: string, data?: unknown) =>\n events.push({\n at: now(),\n level,\n message,\n ...(currentSub ? { subId: currentSub.id } : {}),\n ...(data === undefined ? {} : { data }),\n });\n const subEvent: StepLogger['subEvent'] = (e) =>\n events.push({\n at: now(),\n level: e.status === 'failed' ? 'error' : e.status === 'skipped' ? 'warn' : 'info',\n message: e.message ?? e.phase ?? e.name,\n subId: e.id,\n name: e.name,\n ...(e.group === undefined ? {} : { group: e.group }),\n ...(e.phase === undefined ? {} : { phase: e.phase }),\n ...(e.status === undefined ? {} : { status: e.status }),\n ...(e.data === undefined ? {} : { data: e.data }),\n });\n const subProcess: StepLogger['subProcess'] = async (name, body, opts) => {\n const id = opts?.id ?? globalThis.crypto.randomUUID();\n const group = opts?.group;\n const start = now();\n const prevSub = currentSub;\n currentSub = { id };\n let terminal = false;\n const emit = (status: 'ok' | 'failed' | 'skipped', message?: string, data?: unknown) => {\n if (terminal) return;\n terminal = true;\n subEvent({ id, name, group, status, message, data: withDuration(start, now, data) });\n };\n const handle: SubProcessHandle = {\n phase: (phase, data) => {\n if (!terminal) subEvent({ id, name, group, phase, data });\n return handle;\n },\n skip: (reason, data) => emit('skipped', reason, data),\n fail: (reason, data) => emit('failed', reason, data),\n };\n try {\n const result = await body(handle);\n emit('ok'); // no-op if the body already called skip()/fail()\n return result;\n } catch (err) {\n emit('failed', err instanceof Error ? err.message : String(err));\n throw err;\n } finally {\n currentSub = prevSub;\n }\n };\n return {\n debug: (m, d) => push('debug', m, d),\n info: (m, d) => push('info', m, d),\n warn: (m, d) => push('warn', m, d),\n error: (m, d) => push('error', m, d),\n sub: (name, status, message, data) =>\n events.push({\n at: now(),\n level: status === 'failed' ? 'error' : status === 'skipped' ? 'warn' : 'info',\n message: message ?? name,\n name,\n status,\n ...(data === undefined ? {} : { data }),\n }),\n subEvent,\n subProcess,\n };\n}\n","import type { RemoteTask, StepEvent, StepLogger, StepResult } from './interfaces';\nimport { createStepLogger } from './step-logger';\n\n/** Canonical step id — the stable identity of a step within a run, used for dedupe and\n * correlation. The format is part of the cross-language wire contract (Python builds the same). */\nexport function stepId(runId: string, seq: number): string {\n return `${runId}:${seq}`;\n}\n\n/** Deterministic signal token a breakpoint suspends on — derived from its logical position. Shared\n * so `ctx.breakpoint` (which records it) and `engine.continue` (which signals it) agree. */\nexport const breakpointToken = (runId: string, seq: number): string => `bp:${runId}:${seq}`;\n\n/** A remote-worker step body. The optional `log` records sub-process outcomes and debug/error\n * lines that ride back on the result — the TypeScript twin of the Python SDK's `StepContext`. */\nexport type StepHandler = (input: unknown, log: StepLogger) => Promise<unknown> | unknown;\n\n/**\n * Run `handler` for `task` and produce the wire-format {@link StepResult}. Pure (no transport,\n * no I/O beyond the handler), so every transport — and any language port — can share the exact\n * same completed / failed / no-handler contract instead of re-deriving it.\n */\nexport async function runStepHandler(\n task: RemoteTask,\n handler: StepHandler | undefined,\n): Promise<StepResult> {\n // Stamp the worker's pickup time so the engine can report queue-wait (startedAt − enqueuedAt).\n // This is the one place every transport funnels through, so timing comes for free everywhere.\n const base = { runId: task.runId, seq: task.seq, stepId: task.stepId, startedAt: Date.now() };\n if (!handler) {\n return {\n ...base,\n status: 'failed',\n error: { message: `no handler for ${task.name}`, retryable: false },\n };\n }\n const events: StepEvent[] = [];\n const withEvents = (result: StepResult): StepResult =>\n events.length > 0 ? { ...result, events } : result;\n try {\n const output = await handler(task.input, createStepLogger(events, Date.now));\n return withEvents({ ...base, status: 'completed', output });\n } catch (err) {\n // Carry `code`/`retryable` off the thrown error if present, so the engine's durable retry can\n // honour a worker's \"don't retry this\" verdict (e.g. a declined card).\n const e = err as { message?: string; code?: string; retryable?: boolean };\n return withEvents({\n ...base,\n status: 'failed',\n error: {\n message: err instanceof Error ? err.message : String(err),\n ...(typeof e?.code === 'string' ? { code: e.code } : {}),\n ...(typeof e?.retryable === 'boolean' ? { retryable: e.retryable } : {}),\n },\n });\n }\n}\n","import type { StepCheckpoint, StepError, StepEvent, StepKind } from './interfaces';\nimport { stepId } from './protocol';\n\n/** Drop an empty events array to `undefined` (the repeated `events?.length ? events : undefined`). */\nfunction nonEmptyEvents(events: StepEvent[] | undefined): StepEvent[] | undefined {\n return events && events.length > 0 ? events : undefined;\n}\n\n/**\n * Build a *phased* step checkpoint — one with distinct enqueue/run/finish timestamps (a local step\n * that is running/completed/failed, or a pending remote/sleep step). Computes the deterministic\n * `stepId` and normalizes empty event arrays, so the engine's running/completed/failed/pending\n * checkpoint literals are constructed in exactly one place instead of ~8.\n *\n * For instantaneous checkpoints (sleep timers, markers, delivered signals) use {@link instantCheckpoint}.\n */\nexport function stepCheckpoint(p: {\n runId: string;\n seq: number;\n name: string;\n kind: StepKind;\n status: StepCheckpoint['status'];\n attempts: number;\n enqueuedAt: Date;\n startedAt: Date;\n finishedAt: Date;\n input?: unknown;\n output?: unknown;\n error?: StepError | undefined;\n events?: StepEvent[] | undefined;\n workerGroup?: string | undefined;\n wakeAt?: number | undefined;\n parallelGroup?: string | undefined;\n}): StepCheckpoint {\n return {\n runId: p.runId,\n seq: p.seq,\n name: p.name,\n kind: p.kind,\n stepId: stepId(p.runId, p.seq),\n status: p.status,\n input: p.input,\n output: p.output,\n error: p.error,\n events: nonEmptyEvents(p.events),\n attempts: p.attempts,\n workerGroup: p.workerGroup,\n wakeAt: p.wakeAt,\n parallelGroup: p.parallelGroup,\n enqueuedAt: p.enqueuedAt,\n startedAt: p.startedAt,\n finishedAt: p.finishedAt,\n };\n}\n\n/**\n * Build an *instantaneous* checkpoint — one with no distinct enqueue/run/finish phases (a durable\n * sleep timer, a breakpoint marker, a delivered signal, a published `setEvent` value, a `patched`\n * marker). All three timestamps collapse to now and `attempts` is 1. Collapses what was five\n * near-identical 10-field `saveCheckpoint({...})` literals into one builder.\n */\nexport function instantCheckpoint(p: {\n runId: string;\n seq: number;\n name: string;\n kind: StepKind;\n status?: StepCheckpoint['status'];\n output?: unknown;\n wakeAt?: number;\n parallelGroup?: string;\n}): StepCheckpoint {\n const at = new Date();\n return {\n runId: p.runId,\n seq: p.seq,\n name: p.name,\n kind: p.kind,\n stepId: stepId(p.runId, p.seq),\n status: p.status ?? 'completed',\n output: p.output,\n wakeAt: p.wakeAt,\n parallelGroup: p.parallelGroup,\n attempts: 1,\n enqueuedAt: at,\n startedAt: at,\n finishedAt: at,\n };\n}\n","/**\n * Thrown inside a step to signal an unrecoverable failure: the engine will NOT retry it,\n * regardless of the step's `retries` setting, and fails the run immediately. Use it for\n * business errors that retrying cannot fix (e.g. a declined card, invalid input).\n */\nexport class FatalError extends Error {\n readonly code?: string | undefined;\n constructor(message: string, code?: string) {\n super(message);\n this.name = 'FatalError';\n this.code = code;\n }\n}\n\n/**\n * Thrown by `start` when a singleton workflow's wait queue is full: the count of in-flight + gated\n * runs sharing the key already equals `limit + maxQueueDepth`, so admitting another would let the\n * same-key backlog grow unbounded. Back-pressure — the caller should retry later or shed load. Only\n * raised when {@link SingletonConfig.maxQueueDepth} is set (omit it for the old unbounded behavior).\n */\nexport class SingletonQueueFullError extends Error {\n readonly workflow: string;\n readonly key: string;\n readonly maxQueueDepth: number;\n constructor(workflow: string, key: string, maxQueueDepth: number) {\n super(\n `singleton queue for ${workflow} key \"${key}\" is full (maxQueueDepth=${maxQueueDepth}); retry later`,\n );\n this.name = 'SingletonQueueFullError';\n this.workflow = workflow;\n this.key = key;\n this.maxQueueDepth = maxQueueDepth;\n }\n}\n\n/**\n * Internal control signal thrown to suspend a run (e.g. on a durable sleep). Not an error the\n * user should throw or catch; the engine uses it to stop execution and persist `wakeAt`.\n */\nexport class SignalTimeoutError extends Error {\n readonly token: string;\n readonly timeoutMs: number;\n constructor(token: string, timeoutMs: number) {\n super(`timed out after ${timeoutMs}ms waiting for signal \"${token}\"`);\n this.name = 'SignalTimeoutError';\n this.token = token;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Thrown when a remote step produces no result and no heartbeat within its `timeoutMs` window —\n * i.e. the worker is presumed dead. Subject to the step's `retries` (it's retryable), so the engine\n * re-dispatches before giving up.\n */\nexport class RemoteStepTimeout extends Error {\n readonly stepId: string;\n readonly timeoutMs: number;\n constructor(stepId: string, timeoutMs: number) {\n super(`remote step ${stepId} produced no result/heartbeat within ${timeoutMs}ms`);\n this.name = 'RemoteStepTimeout';\n this.stepId = stepId;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Thrown by a remote {@link WorkflowExecutor} (e.g. {@link RemoteWorkflowExecutor}) when an `advance`\n * does not produce its decision within the configured `timeoutMs` — i.e. the worker is presumed gone\n * (the decision was dropped by a stall/redelivery or an instance restart spanning the in-memory waiter\n * map). Crucially this is NOT a run failure: the work may have actually completed and only the decision\n * was lost. The engine treats it as RECOVERABLE — it releases the run lease and leaves the run\n * `running` so `recoverIncomplete` re-drives it deterministically (replaying completed steps from\n * history). Distinct from a real executor error, which still fails the run.\n *\n * OPT-IN: only thrown when the executor was constructed with a `timeoutMs`. Absent a timeout, the\n * engine awaits the decision with its prior (unbounded) behavior — so existing users see no change.\n *\n * Known hazard: a timeout that fires while a worker is LEGITIMATELY still executing a not-yet-\n * checkpointed step will re-drive and re-run that in-flight step → DUPLICATE side effects. Therefore\n * the timeout is only safe when set GENEROUSLY (longer than the longest legitimate single turn). The\n * robust fix — a liveness/heartbeat-rearmed deadline so only a genuinely-dead worker re-drives — is the\n * documented follow-up (see the Track A diagnosis doc, \"Part B\").\n */\nexport class RemoteWorkflowTimeout extends Error {\n readonly taskId: string;\n readonly timeoutMs: number;\n constructor(taskId: string, timeoutMs: number) {\n super(\n `remote workflow task ${taskId} produced no decision within ${timeoutMs}ms — presumed dropped; re-driving via recovery`,\n );\n this.name = 'RemoteWorkflowTimeout';\n this.taskId = taskId;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Thrown on resume when the workflow code no longer matches the recorded history: the step at a\n * logical position has a different name/kind than the checkpoint saved there. This means the\n * workflow definition changed (a step was added/removed/reordered) under an in-flight run without a\n * new `@Workflow` version — continuing would replay the wrong checkpoint into the wrong step and\n * silently corrupt the run, so the engine fails loudly instead. Register a new workflow version for\n * breaking changes (old runs finish on the version they started on).\n */\nexport class NonDeterminismError extends Error {\n readonly runId: string;\n readonly seq: number;\n constructor(runId: string, seq: number, expected: string, recorded: string) {\n super(\n `non-determinism at ${runId}#${seq}: code expects \"${expected}\" but history recorded ` +\n `\"${recorded}\". The workflow changed under an in-flight run — register a new @Workflow version.`,\n );\n this.name = 'NonDeterminismError';\n this.runId = runId;\n this.seq = seq;\n }\n}\n\n/**\n * Thrown by `ctx.all` when one or more parallel child workflows fail. Carries the per-item failures\n * (input index, child run id, error message) and presents an aggregate message summarizing the count\n * and the failing ids — the wait-all/fail-fast counterpart to a single child's FatalError. Mirrors\n * the Python SDK's `GatherFailed`.\n */\nexport class GatherError extends Error {\n readonly failures: { index: number; id: string; error: string }[];\n constructor(failures: { index: number; id: string; error: string }[], total?: number) {\n const ids = failures.map((f) => f.id).join(', ');\n const denom = total ?? failures.length;\n super(`ctx.all: ${failures.length} of ${denom} child(ren) failed: ${ids}`);\n this.name = 'GatherError';\n this.failures = failures;\n }\n}\n\nexport class WorkflowSuspended extends Error {\n /** Epoch ms to auto-resume (durable sleep), or undefined when waiting on an external signal. */\n readonly wakeAt?: number | undefined;\n constructor(wakeAt?: number) {\n super('workflow suspended');\n this.name = 'WorkflowSuspended';\n this.wakeAt = wakeAt;\n }\n}\n\n/**\n * Thrown by `ctx.continueAsNew(input)` to end the current run and hand off to a fresh execution of\n * the same workflow with a clean history — for long-running / looping workflows that would otherwise\n * accumulate unbounded checkpoints. The engine completes this run and starts the next one.\n */\nexport class ContinueAsNew extends Error {\n constructor(readonly input: unknown) {\n super('workflow continued as new');\n this.name = 'ContinueAsNew';\n }\n}\n","import { FatalError } from './errors';\nimport type { WorkflowCtx } from './interfaces';\n\n/** One operation on a durable entity: mutate `state` in place and/or return a result. */\nexport type EntityHandler<S = unknown> = (state: S, arg: unknown) => unknown | Promise<unknown>;\n\n/** A durable keyed entity (a virtual object): per-key serialized handlers over durable state. */\nexport interface EntityConfig<S = unknown> {\n /** Build the initial state for a fresh key. */\n initialState: () => S;\n /** Operation handlers, keyed by op name. Each runs serially per key, exactly once. */\n handlers: Record<string, EntityHandler<S>>;\n}\n\n/** The slice of the engine the entity subsystem needs (so it stays a standalone module). */\nexport interface EntityHost {\n register(\n name: string,\n version: string,\n fn: (ctx: WorkflowCtx, input: unknown) => Promise<unknown>,\n ): void;\n signalWithStart(\n workflow: string,\n input: unknown,\n runId: string,\n signal: { token: string; payload?: unknown },\n ): Promise<{ runId: string }>;\n getEvent<T>(runId: string, key: string): Promise<T | undefined>;\n signal(token: string, payload: unknown): Promise<unknown>;\n}\n\nconst ENTITY_WORKFLOW = '__entity';\nconst entityRunId = (name: string, key: string): string => `entity:${name}:${key}`;\n\n/**\n * Durable keyed **entities** (virtual objects): a keyed actor whose handlers run **serialized per\n * key** over **durable state**, exactly once. Each key is one long-lived run (`entity:<name>:<key>`)\n * processing ops in order. Drive it with `signal` (fire) or `ctx.callEntity` (call + await result),\n * read state with `getState`. Registers its built-in runner on construction.\n */\nexport class Entities {\n private readonly configs = new Map<string, EntityConfig>();\n\n constructor(private readonly host: EntityHost) {\n host.register(ENTITY_WORKFLOW, '1', (ctx, input) => this.run(ctx, input));\n }\n\n register<S>(name: string, config: EntityConfig<S>): void {\n this.configs.set(name, config as EntityConfig);\n }\n\n /** Deliver an op to an entity's runner, starting it on first contact. `reply` (a signal token)\n * receives the handler's result, for `ctx.callEntity`. */\n dispatch(\n name: string,\n key: string,\n op: string,\n arg: unknown,\n reply?: string,\n ): Promise<{ runId: string }> {\n const runId = entityRunId(name, key);\n return this.host.signalWithStart(ENTITY_WORKFLOW, { name, key }, runId, {\n token: runId,\n payload: { op, arg, reply },\n });\n }\n\n async signal(name: string, key: string, op: string, arg?: unknown): Promise<void> {\n await this.dispatch(name, key, op, arg);\n }\n\n getState<S = unknown>(name: string, key: string): Promise<S | undefined> {\n return this.host.getEvent<S>(entityRunId(name, key), 'state');\n }\n\n /** The built-in runner: one long-lived run per key, processing ops serially over state. */\n private async run(ctx: WorkflowCtx, input: unknown): Promise<unknown> {\n const { name, key } = input as { name: string; key: string };\n const config = this.configs.get(name);\n if (!config) throw new FatalError(`entity \"${name}\" is not registered`);\n const token = entityRunId(name, key);\n let state = config.initialState();\n for (let i = 0; ; i += 1) {\n const msg = (await ctx.waitForSignal(token)) as { op: string; arg: unknown; reply?: string };\n // Run the handler and snapshot the (possibly mutated) state in ONE checkpoint, so replay\n // restores the state from the checkpoint instead of re-running the handler.\n const out = await ctx.step(`op:${i}`, async () => {\n const handler = config.handlers[msg.op];\n if (!handler) throw new FatalError(`entity \"${name}\" has no handler for op \"${msg.op}\"`);\n const result = await handler(state, msg.arg);\n return { result, state };\n });\n state = out.state; // carry state forward (and restore it from the checkpoint on replay)\n await ctx.setEvent('state', state); // publish for getState\n if (msg.reply) {\n await ctx.step(`reply:${i}`, async () => {\n await this.host.signal((msg as { reply: string }).reply, out.result);\n });\n }\n }\n }\n}\n","import { SignalTimeoutError } from './errors';\nimport type { WorkflowCtx } from './interfaces';\n\n/** How `onEvent` triggers are coalesced into fewer runs (see `@Workflow({ debounce | batch })`). */\nexport type EventBatchConfig =\n | { mode: 'debounce'; windowMs: number }\n | { mode: 'batch'; maxSize: number; windowMs: number };\n\n/** The slice of the engine the accumulators need (so they stay a standalone module). */\nexport interface AccumulatorHost {\n register(\n name: string,\n version: string,\n fn: (ctx: WorkflowCtx, input: unknown) => Promise<unknown>,\n ): void;\n signalWithStart(\n workflow: string,\n input: unknown,\n runId: string,\n signal: { token: string; payload?: unknown },\n ): Promise<{ runId: string }>;\n}\n\nconst accToken = (target: string): string => `__evtacc__:${target}`;\n\n/**\n * Built-in workflows that coalesce `onEvent` triggers. Each is a long-lived per-target accumulator\n * fed by `signalWithStart`: it collects payloads then starts the target once, and `continueAsNew`s to\n * re-arm for the next burst. Signal buffering keeps the re-arm race-free. Registers its runners on\n * construction.\n */\nexport class EventAccumulators {\n constructor(private readonly host: AccumulatorHost) {\n host.register('__evt_debounce', '1', (ctx, input) => this.debounce(ctx, input));\n host.register('__evt_batch', '1', (ctx, input) => this.batch(ctx, input));\n }\n\n /** Route an `onEvent` payload into its target's debounce/batch accumulator. */\n route(target: string, config: EventBatchConfig, payload: unknown): Promise<{ runId: string }> {\n const [workflow, input] =\n config.mode === 'debounce'\n ? (['__evt_debounce', { target, windowMs: config.windowMs }] as const)\n : ([\n '__evt_batch',\n { target, maxSize: config.maxSize, windowMs: config.windowMs },\n ] as const);\n return this.host.signalWithStart(workflow, input, accToken(target), {\n token: accToken(target),\n payload,\n });\n }\n\n /** Fire the target with the LAST payload once events have been quiet for `windowMs`. */\n private async debounce(ctx: WorkflowCtx, input: unknown): Promise<unknown> {\n const { target, windowMs } = input as { target: string; windowMs: number };\n const token = accToken(target);\n let last = await ctx.waitForSignal(token); // park for the first event of a burst\n for (;;) {\n try {\n last = await ctx.waitForSignal(token, { timeoutMs: windowMs }); // extend on each event\n } catch (e) {\n if (e instanceof SignalTimeoutError) break; // quiet for `windowMs` → fire\n throw e; // WorkflowSuspended / ContinueAsNew etc. must propagate\n }\n }\n await ctx.startChild(target, last);\n return ctx.continueAsNew(input); // re-arm\n }\n\n /** Fire the target with all payloads (`{ events }`) once `maxSize` or `windowMs` from the first. */\n private async batch(ctx: WorkflowCtx, input: unknown): Promise<unknown> {\n const { target, maxSize, windowMs } = input as {\n target: string;\n maxSize: number;\n windowMs: number;\n };\n const token = accToken(target);\n const events: unknown[] = [await ctx.waitForSignal(token)]; // park for the first\n const deadline = (await ctx.now()) + windowMs;\n while (events.length < maxSize) {\n const remaining = deadline - (await ctx.now());\n if (remaining <= 0) break;\n try {\n events.push(await ctx.waitForSignal(token, { timeoutMs: remaining }));\n } catch (e) {\n if (e instanceof SignalTimeoutError) break; // window elapsed → fire what we have\n throw e; // WorkflowSuspended / ContinueAsNew etc. must propagate\n }\n }\n await ctx.startChild(target, { events });\n return ctx.continueAsNew(input); // re-arm\n }\n}\n","// Named events: pub/sub on top of the signal-waiter table. A `ctx.waitForEvent(name, { match })`\n// registers a signal waiter whose token encodes the event name + match criteria (base64 so they\n// never contain the `:` delimiter); `engine.publishEvent(name, payload)` lists the waiters for that\n// name by token prefix, checks each one's match against the payload, and signals the ones that pass.\n// No schema change beyond a `listSignalWaiters(prefix)` store method.\n\nconst enc = (s: string): string => Buffer.from(s, 'utf8').toString('base64');\nconst dec = (s: string): string => Buffer.from(s, 'base64').toString('utf8');\n\n/** Token prefix for every waiter on `name` — used by `listSignalWaiters` to fan an event out. */\nexport function eventPrefix(name: string): string {\n return `event:${enc(name)}:`;\n}\n\n/** Build the unique waiter token for one `waitForEvent` call (name + match + run position). */\nexport function eventToken(\n name: string,\n match: Record<string, unknown> | undefined,\n runId: string,\n seq: number,\n): string {\n return `${eventPrefix(name)}${enc(JSON.stringify(match ?? {}))}:${runId}#${seq}`;\n}\n\n/** The match criteria embedded in an event waiter token (the 3rd `:`-segment is the base64 match). */\nexport function eventMatchOf(token: string): Record<string, unknown> {\n try {\n return JSON.parse(dec(token.split(':')[2] ?? '')) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\n/** Whether `payload` satisfies a waiter's `match`: every match key deep-equals the payload's value. */\nexport function eventMatches(payload: unknown, match: Record<string, unknown>): boolean {\n const keys = Object.keys(match);\n if (keys.length === 0) return true; // no criteria → matches any payload of this name\n if (!payload || typeof payload !== 'object') return false;\n const p = payload as Record<string, unknown>;\n return keys.every((k) => JSON.stringify(p[k]) === JSON.stringify(match[k]));\n}\n","import type { SingletonConfig } from './engine';\nimport { SingletonQueueFullError } from './errors';\nimport type { StateStore, WorkflowRun } from './interfaces';\n\nconst SINGLETON_RETRY_MS = 1000;\n/**\n * Max jitter (ms, each direction) added to {@link SINGLETON_RETRY_MS} so a queue of N gated runs\n * doesn't wake in lockstep and stampede the admission scan. Each retry picks an independent offset\n * in `[-SINGLETON_RETRY_JITTER_MS, +SINGLETON_RETRY_JITTER_MS]`.\n */\nconst SINGLETON_RETRY_JITTER_MS = 250;\n\nexport interface SingletonGateDeps {\n store: Pick<StateStore, 'listRuns' | 'updateRun'>;\n clock: () => number;\n /** Hand a gated run to the run dispatcher (fire-and-forget, like the engine's other dispatches). */\n dispatch: (runId: string) => void;\n /** Resolve a settled run's singleton config from the engine's workflow registry. */\n configFor: (run: WorkflowRun) => SingletonConfig | undefined;\n}\n\n/**\n * Per-key serialization for singleton workflows — start-time back-pressure, FIFO race-free\n * admission, and notify-on-release wakeups. Extracted from {@link WorkflowEngine} so the whole\n * singleton feature lives in one place instead of being smeared across `start`, `execute`, both run\n * loops, and `cancel`.\n */\nexport class SingletonGate {\n constructor(private readonly deps: SingletonGateDeps) {}\n\n /** The tag a singleton run carries, so the gate can find others sharing its key. */\n tag(cfg: SingletonConfig, input: unknown): string {\n return `singleton:${cfg.key(input)}`;\n }\n\n /** Next wake time for a gated run: the base retry delay jittered to avoid a wakeup stampede. */\n retryWakeAt(): number {\n return (\n this.deps.clock() +\n SINGLETON_RETRY_MS +\n Math.floor((Math.random() * 2 - 1) * SINGLETON_RETRY_JITTER_MS)\n );\n }\n\n /**\n * Reject a start that would grow the same-key backlog past `limit + maxQueueDepth` (counting\n * `pending`/`running`/`suspended` runs sharing the key in one scan). No-op when no `maxQueueDepth`\n * is configured.\n */\n async assertCapacity(workflow: string, cfg: SingletonConfig, input: unknown): Promise<void> {\n if (cfg.maxQueueDepth == null) return;\n const cap = (cfg.limit ?? 1) + cfg.maxQueueDepth;\n const queued = await this.deps.store.listRuns({\n tag: this.tag(cfg, input),\n workflow,\n statuses: ['pending', 'running', 'suspended'],\n });\n if (queued.length >= cap) {\n throw new SingletonQueueFullError(workflow, cfg.key(input), cfg.maxQueueDepth);\n }\n }\n\n /**\n * Whether `run` may run now under its key: it's among the `limit` oldest in-flight (running or\n * suspended) runs sharing the key, by `(createdAt, id)` order. A consistent store gives every\n * instance the same ordering, so admission is race-free + FIFO.\n */\n async admit(run: WorkflowRun, cfg: SingletonConfig): Promise<boolean> {\n // ONE scan for both in-flight statuses; the total `(createdAt, id)` sort makes admission order\n // independent of the store's row order, preserving the FIFO + race-free-across-instances contract.\n const inflight = (\n await this.deps.store.listRuns({\n tag: this.tag(cfg, run.input),\n workflow: run.workflow,\n statuses: ['running', 'suspended'],\n })\n ).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime() || a.id.localeCompare(b.id));\n const idx = inflight.findIndex((r) => r.id === run.id);\n return idx >= 0 && idx < (cfg.limit ?? 1);\n }\n\n /**\n * Notify-on-release: a singleton run settled (freeing a slot), so dispatch the oldest gated\n * (`suspended` + same tag) waiters now instead of waiting for their ~1s retry timer. Each re-checks\n * admission in the executor and runs only if it actually wins a slot, so FIFO/race-free guarantees\n * hold; the durable timer remains the cross-instance/crash fallback.\n */\n async wakeNext(settled: WorkflowRun): Promise<void> {\n const cfg = this.deps.configFor(settled);\n if (!cfg) return;\n const tag = settled.tags?.find((t) => t.startsWith('singleton:'));\n if (!tag) return;\n const gated = (\n await this.deps.store.listRuns({ tag, workflow: settled.workflow, statuses: ['suspended'] })\n ).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime() || a.id.localeCompare(b.id));\n for (const next of gated.slice(0, cfg.limit ?? 1)) {\n // Clear the durable retry timer as we hand the run over, so the timer poller can't also pick it\n // up and double-dispatch. Only for runs that carry a wakeAt; dispatch after the clear commits.\n if (next.wakeAt != null) {\n await this.deps.store\n .updateRun(next.id, { wakeAt: undefined, updatedAt: new Date() })\n .catch(() => undefined);\n }\n this.deps.dispatch(next.id);\n }\n }\n}\n","import type {\n GroupHealth,\n Heartbeat,\n NamedTransport,\n RemoteTask,\n StepResult,\n WorkflowStepEvent,\n} from './interfaces';\n\n/**\n * An ordered pool of named transports. The engine dispatches on the first and fails over to the\n * next on a dispatch error; a step can pin one by id. Pure transport plumbing — no run lifecycle —\n * so it lives apart from the engine.\n */\nexport class TransportPool {\n constructor(private readonly transports: NamedTransport[]) {}\n\n get size(): number {\n return this.transports.length;\n }\n\n /** Register the engine's result/heartbeat/step-event handlers on EVERY transport — a result can come\n * back on whichever one delivered the task, so failover stays symmetric. `onStepEvent` is wired only\n * on transports that carry streamed workflow step lifecycle (BullMQ); others simply skip it. */\n bind(\n onResult: (result: StepResult) => Promise<void>,\n onHeartbeat: (beat: Heartbeat) => Promise<void>,\n onStepEvent?: (event: WorkflowStepEvent) => Promise<void>,\n ): void {\n for (const { transport } of this.transports) {\n transport.onResult(onResult);\n transport.onHeartbeat(onHeartbeat);\n if (onStepEvent && transport.onStepEvent) {\n transport.onStepEvent(onStepEvent);\n }\n }\n }\n\n /**\n * Dispatch `task` over the pool: try the preferred (or first) transport, fail over to the next on\n * a dispatch error, and stamp the task with the id of the transport that accepted it (so a worker\n * replies on the matching one). Throws if every transport fails.\n */\n async dispatch(task: Omit<RemoteTask, 'transport'>, preferId?: string): Promise<void> {\n let lastErr: unknown;\n for (const { id, transport } of this.ordered(preferId)) {\n try {\n await transport.dispatch({ ...task, transport: id });\n return;\n } catch (err) {\n lastErr = err;\n }\n }\n throw lastErr ?? new Error('no transport accepted the dispatch');\n }\n\n /** Worker-health for `group`, merged across every transport that can report it (a group's queue\n * and its workers may live on any pinned transport). Undefined when no transport implements\n * `groupHealth` (e.g. a pure in-process transport — nothing to introspect). */\n async groupHealth(group: string): Promise<GroupHealth | undefined> {\n const reports: GroupHealth[] = [];\n for (const { transport } of this.transports) {\n if (transport.groupHealth) reports.push(await transport.groupHealth(group));\n }\n if (reports.length === 0) return undefined;\n return {\n group,\n depth: reports.reduce((sum, r) => sum + r.depth, 0),\n liveWorkers: reports.flatMap((r) => r.liveWorkers),\n };\n }\n\n /** Distinct worker groups with a live heartbeat, merged across every transport that can report it. */\n async listWorkerGroups(): Promise<string[]> {\n const groups = new Set<string>();\n for (const { transport } of this.transports) {\n if (transport.listWorkerGroups) {\n for (const g of await transport.listWorkerGroups()) groups.add(g);\n }\n }\n return [...groups];\n }\n\n /** Pinned `preferId` first, then the rest (failover order). */\n private ordered(preferId?: string): NamedTransport[] {\n if (!preferId) return this.transports;\n const pref = this.transports.filter((t) => t.id === preferId);\n if (pref.length === 0) throw new Error(`transport \"${preferId}\" is not registered`);\n return [...pref, ...this.transports.filter((t) => t.id !== preferId)];\n }\n}\n","import { FatalError } from './errors';\n\n/**\n * The payload an external `ctx.task` / child run delivers back on its completion signal: either a\n * value or a failure. One typed envelope so `task` and `child` share the same unwrap (instead of\n * sniffing ad-hoc `__error` keys).\n */\nexport type Completion<T> = { ok: true; value: T } | { ok: false; error: string };\n\n/** Read a `Completion` from a signal payload: return the value, or throw a FatalError if it failed. */\nexport function unwrapCompletion<T>(payload: unknown, label: string): T {\n const c = payload as Completion<T> | null;\n if (c && typeof c === 'object' && 'ok' in c && c.ok === false) {\n throw new FatalError(`${label} failed: ${c.error}`);\n }\n return (c as { value: T } | null)?.value as T;\n}\n","/**\n * A **workflow reference** is how one workflow names another to call it: either a registered workflow\n * **name** (a string — the only option across runtimes, e.g. a Python workflow) or, for a same-runtime\n * TypeScript workflow, its **class**. The class carries the input/output types through the call, so\n * `ctx.child(ShippingWorkflow, input)` type-checks the input and returns a typed result — while a\n * string stays available for the cross-runtime case.\n */\n\n/**\n * The symbol the `@Workflow` decorator stamps a workflow's registered name onto, so a class ref can\n * be resolved back to its name. A global-registry symbol (`Symbol.for`) so it survives duplicate\n * copies of this package in a dependency tree.\n */\nexport const WORKFLOW_NAME_KEY: unique symbol = Symbol.for('nestjs-durable:workflow-name');\n\n/** Structural shape of a `@Workflow` class — its `run(ctx, input)` carries the input/output types. */\nexport type WorkflowClass<TInput = unknown, TOutput = unknown> = abstract new (\n ...args: never[]\n) => {\n run(ctx: never, input: TInput): Promise<TOutput> | TOutput;\n};\n\n/** A workflow reference: a registered name (cross-runtime) or a workflow class (typed, same-runtime). */\nexport type WorkflowRef<TInput = unknown, TOutput = unknown> =\n | string\n | WorkflowClass<TInput, TOutput>;\n\n/** The input type a workflow class's `run` accepts. */\nexport type WorkflowInputOf<C> = C extends abstract new (\n ...args: never[]\n) => {\n run(ctx: never, input: infer I): unknown;\n}\n ? I\n : unknown;\n\n/** The output type a workflow class's `run` resolves to (Promise unwrapped). */\nexport type WorkflowOutputOf<C> = C extends abstract new (\n ...args: never[]\n) => {\n run(ctx: never, input: never): infer R;\n}\n ? Awaited<R>\n : unknown;\n\n/**\n * Resolve a {@link WorkflowRef} to its registered workflow name: a string is returned as-is; a\n * `@Workflow` class is resolved via the name the decorator stamped on it. Throws if a class was\n * never decorated (so it carries no registered name).\n */\nexport function workflowName(ref: WorkflowRef): string {\n if (typeof ref === 'string') return ref;\n const name = (ref as { [WORKFLOW_NAME_KEY]?: string })[WORKFLOW_NAME_KEY];\n if (!name) {\n throw new Error(\n `workflow class ${ref.name} has no registered name — is it decorated with @Workflow({ name })?`,\n );\n }\n return name;\n}\n","import { backoffDelay } from './backoff';\nimport { instantCheckpoint } from './checkpoints';\nimport { unwrapCompletion } from './completion';\nimport { parseDuration } from './duration';\nimport {\n ContinueAsNew,\n FatalError,\n GatherError,\n NonDeterminismError,\n SignalTimeoutError,\n WorkflowSuspended,\n} from './errors';\nimport { eventToken } from './events';\nimport type {\n ChildCallOptions,\n DurableWebhook,\n RemoteStepDef,\n StateStore,\n StepCheckpoint,\n StepError,\n StepEvent,\n StepInvocation,\n StepKind,\n StepLogger,\n StepOptions,\n WorkflowCtx,\n} from './interfaces';\nimport { breakpointToken } from './protocol';\nimport { createStepLogger } from './step-logger';\nimport { type WorkflowRef, workflowName } from './workflow-ref';\n\n/** Normalize the `ctx.child`/`ctx.startChild` 3rd arg: a bare string is shorthand for `{ childId }`. */\nfunction normalizeChildOptions(options?: string | ChildCallOptions): ChildCallOptions {\n return typeof options === 'string' ? { childId: options } : (options ?? {});\n}\n\n/** A saga undo registered by a completed step, kept with its step name for visibility on failure. */\nexport interface Compensation {\n name: string;\n fn: () => Promise<void>;\n}\n\n/** A finished local step the host should checkpoint and announce (completed or failed). */\nexport interface StepRecord {\n runId: string;\n seq: number;\n name: string;\n kind: StepKind;\n input?: unknown;\n events?: StepEvent[] | undefined;\n attempts: number;\n enqueuedAt: Date;\n startedAt: Date;\n workerGroup?: string | undefined;\n}\n\n/**\n * The narrow surface {@link createWorkflowCtx} needs from the engine — the seam between the\n * authoring API (this module) and the orchestrator (the engine owns lifecycle: emitting events,\n * suspending/resuming runs, dispatching remote steps).\n */\nexport interface CtxHost {\n readonly store: StateStore;\n /**\n * Per-execution checkpoint snapshot, loaded ONCE at execution start (the completed prefix this\n * replay walks). Lets each primitive read the prefix from memory instead of a per-call DB SELECT\n * (the O(N²) replay-reads fix). A seq ABSENT from the map is NOT cached — the primitive falls back\n * to the live store, so the checkpoint this resume is waking on (signal/timer/child, written after\n * the snapshot) is always read fresh. New checkpoints written during this execution are inserted\n * into the map so any later same-execution read sees them. Undefined ⇒ always hit the store.\n */\n readonly replay?: Map<number, StepCheckpoint> | undefined;\n clock(): number;\n webhookUrl?: ((token: string) => string) | undefined;\n /** Mark a local step's body as started — emits `step.started` and (optionally) a `running` checkpoint. */\n startStep(step: StepRecord): Promise<void>;\n completeStep(step: StepRecord & { output: unknown }): Promise<void>;\n failStep(step: StepRecord & { error: StepError }): Promise<void>;\n callRemote<TInput, TOutput>(\n runId: string,\n seq: number,\n step: RemoteStepDef<TInput, TOutput>,\n input: TInput,\n queue?: string,\n transport?: string,\n admission?: { priority?: number | undefined; fairnessKey?: string | undefined },\n ): Promise<TOutput>;\n /** Start a child run once, deferred so it can't reentrantly resume a still-running parent. */\n startChild(workflow: string, input: unknown, id: string, priority?: number): void;\n /** Deliver an op to a durable entity (deferred), optionally with a `reply` token for the result. */\n signalEntity?(name: string, key: string, op: string, arg: unknown, reply?: string): void;\n /** Run a local step body through the registered step interceptors (identity if none). */\n interceptStep?<T>(invocation: StepInvocation, body: () => Promise<T>): Promise<T>;\n}\n\n/** The per-run logical position counter. `rewind()` gives a position back (see `ctx.patched`). */\nclass Position {\n private seq = -1;\n next(): number {\n this.seq += 1;\n return this.seq;\n }\n rewind(): void {\n this.seq -= 1;\n }\n}\n\n/**\n * Build the {@link WorkflowCtx} handed to a workflow body. Every primitive is a closure over the\n * position counter (the per-run logical position) and the saga `compensations` stack, so `task`/\n * `child` compose `step`/`waitForSignal` directly. All durability goes through {@link CtxHost}, so\n * the workflow body stays deterministic.\n */\nexport function createWorkflowCtx(\n host: CtxHost,\n runId: string,\n compensations: Compensation[],\n workflow = '',\n): WorkflowCtx {\n const { store, replay } = host;\n const pos = new Position();\n\n // Read the checkpoint at `seq`: from the per-execution snapshot when present (no DB round-trip),\n // otherwise from the live store. Absence in the snapshot means \"written after the snapshot\" (the\n // signal/timer/child this resume wakes on, or nothing yet) — those MUST hit the store. Identical\n // behaviour to a raw `store.getCheckpoint`, just memoized for the completed prefix.\n const readCheckpoint = (seq: number): Promise<StepCheckpoint | null> | StepCheckpoint => {\n const hit = replay?.get(seq);\n if (hit !== undefined) return hit;\n return store.getCheckpoint(runId, seq);\n };\n\n // Persist a checkpoint AND reflect it in the snapshot, so a later same-execution read of this seq\n // (e.g. a re-read within the same call) sees it instead of falling back to the store.\n const writeCheckpoint = async (cp: StepCheckpoint): Promise<void> => {\n await store.saveCheckpoint(cp);\n replay?.set(cp.seq, cp);\n };\n\n const step = async <T>(\n name: string,\n fn: (log: StepLogger) => Promise<T>,\n options?: StepOptions,\n ): Promise<T> => {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.name !== name) {\n throw new NonDeterminismError(runId, current, name, existing.name);\n }\n if (existing && existing.status === 'completed') {\n // Register the compensation on replay too, so a saga undoes ALL completed steps — even\n // those done in an earlier (since-suspended) pass — not just the ones run this pass.\n if (options?.compensate) compensations.push({ name, fn: options.compensate });\n return existing.output as T;\n }\n const maxAttempts = Math.max(1, options?.retries ?? 1);\n const startedAt = new Date();\n // Announce the body has begun (and, when enabled, checkpoint it `running`) so the step is\n // visible in flight — not only once it settles. Skipped on replay: a completed step returns\n // above before reaching here, so this fires once, when the body actually first runs.\n await host.startStep({\n runId,\n seq: current,\n name,\n kind: 'local',\n attempts: 1,\n enqueuedAt: startedAt,\n startedAt,\n });\n for (let attempt = 1; ; attempt += 1) {\n // Events are scoped per attempt — a retry starts a clean log, so the checkpoint reflects\n // only the attempt that actually completed (or the final failing one).\n const events: StepEvent[] = [];\n try {\n const invocation: StepInvocation = {\n runId,\n workflow,\n stepName: name,\n seq: current,\n attempt,\n };\n const body = () => fn(createStepLogger(events, host.clock));\n const output = host.interceptStep\n ? await host.interceptStep(invocation, body)\n : await body();\n await host.completeStep({\n runId,\n seq: current,\n name,\n kind: 'local',\n output,\n events,\n attempts: attempt,\n enqueuedAt: startedAt,\n startedAt,\n });\n if (options?.compensate) compensations.push({ name, fn: options.compensate });\n return output;\n } catch (err) {\n if (err instanceof FatalError || attempt >= maxAttempts) {\n await host.failStep({\n runId,\n seq: current,\n name,\n kind: 'local',\n error: {\n message: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n },\n events,\n attempts: attempt,\n enqueuedAt: startedAt,\n startedAt,\n });\n throw err;\n }\n // Wait out the backoff before the next attempt (no-op when backoffMs is unset).\n const wait = backoffDelay(attempt, options);\n if (wait > 0) await new Promise((resolve) => setTimeout(resolve, wait));\n }\n }\n };\n\n // Exactly-once DB step: run the body and write the step checkpoint in ONE store transaction, so the\n // business write commits atomically with the \"done\" marker (a plain step checkpoints AFTER the body,\n // so a crash in between re-runs it). Replay returns the recorded output without re-running.\n const transaction = async <T>(name: string, fn: (tx: unknown) => Promise<T>): Promise<T> => {\n if (!store.transaction) {\n throw new Error(\n 'ctx.transaction needs a store that supports transactions (the SQL adapters do). Use ctx.step for non-transactional work.',\n );\n }\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.name !== name) {\n throw new NonDeterminismError(runId, current, name, existing.name);\n }\n if (existing && existing.status === 'completed') return existing.output as T;\n return store.transaction(async (tx) => {\n const output = await fn(tx.raw);\n const cp = instantCheckpoint({ runId, seq: current, name, kind: 'local', output });\n await tx.saveCheckpoint(cp);\n // Reflect the committed checkpoint in the snapshot, keeping the writeback invariant uniform.\n replay?.set(current, cp);\n return output;\n });\n };\n\n // Shared by sleep / sleepUntil: record a durable timer at this position and suspend until `wakeAt`\n // (epoch ms). The wakeAt is computed by the caller — but only used on the first run; on replay the\n // recorded checkpoint's wakeAt wins, so a clock change can't shift an already-scheduled timer.\n const suspendUntil = async (wakeAt: () => number): Promise<void> => {\n const current = pos.next();\n const now = host.clock();\n const existing = await readCheckpoint(current);\n if (existing) {\n // Timer already recorded: resume if due, otherwise re-suspend cheaply.\n if (now >= (existing.wakeAt ?? 0)) return;\n throw new WorkflowSuspended(existing.wakeAt ?? now);\n }\n const at = wakeAt();\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name: 'sleep', kind: 'sleep', wakeAt: at }),\n );\n throw new WorkflowSuspended(at);\n };\n\n const sleep = (duration: string | number): Promise<void> =>\n suspendUntil(() => host.clock() + parseDuration(duration));\n\n const sleepUntil = (when: Date | number): Promise<void> =>\n suspendUntil(() => (typeof when === 'number' ? when : when.getTime()));\n\n // End this run and hand off to a fresh execution (clean history) with the new input. Terminal —\n // it always throws, so any code after it in the workflow is unreachable.\n const continueAsNew = (input?: unknown): Promise<never> => {\n throw new ContinueAsNew(input);\n };\n\n // NOTE (determinism): a bounded wait consumes TWO logical positions (deadline + wait), an\n // unbounded one consumes ONE. So adding or removing `{ timeoutMs }` on an existing `waitForSignal`\n // shifts the seq of every later step — treat it as a workflow-version change for in-flight runs.\n // Consume a buffered signal (one delivered before this run was waiting), recording it as the\n // signal checkpoint at `seq` so it resumes immediately instead of suspending. Replay-safe: the\n // checkpoint makes the consumption deterministic.\n const consumeBuffered = async <T>(token: string, seq: number): Promise<{ value: T } | null> => {\n const buffered = await store.takeBufferedSignal(token);\n if (!buffered) return null;\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq,\n name: `signal:${token}`,\n kind: 'signal',\n output: buffered.payload,\n }),\n );\n return { value: buffered.payload as T };\n };\n\n const waitForSignal = async <T>(token: string, opts?: { timeoutMs?: number }): Promise<T> => {\n if (opts?.timeoutMs == null) {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as T;\n const buffered = await consumeBuffered<T>(token, current);\n if (buffered) return buffered.value;\n await store.putSignalWaiter({ token, runId, seq: current });\n throw new WorkflowSuspended();\n }\n const timeoutMs = opts.timeoutMs;\n const deadlineSeq = pos.next();\n const waitSeq = pos.next();\n // The deadline is recorded durably as a timer checkpoint so replay knows it; the run also gets a\n // run-level wakeAt (via WorkflowSuspended) so the timer poller resumes it at the deadline.\n const recorded = await readCheckpoint(deadlineSeq);\n const deadline = recorded?.wakeAt ?? host.clock() + timeoutMs;\n if (!recorded) {\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq: deadlineSeq,\n name: `timeout:${token}`,\n kind: 'sleep',\n wakeAt: deadline,\n }),\n );\n }\n const waited = await readCheckpoint(waitSeq);\n if (waited && waited.status === 'completed') return waited.output as T;\n const buffered = await consumeBuffered<T>(token, waitSeq);\n if (buffered) return buffered.value;\n if (host.clock() >= deadline) {\n await store.takeSignalWaiter(token).catch(() => undefined);\n throw new SignalTimeoutError(token, timeoutMs);\n }\n await store.putSignalWaiter({ token, runId, seq: waitSeq });\n throw new WorkflowSuspended(deadline);\n };\n\n // Wait for a named event delivered by engine.publishEvent(name, payload). Like waitForSignal, but\n // name-based pub/sub with optional `match` filtering — the token embeds name + match (see events.ts),\n // so a publish fans out to the runs whose match the payload satisfies.\n const waitForEvent = async <T>(\n name: string,\n opts?: { match?: Record<string, unknown>; timeoutMs?: number },\n ): Promise<T> => {\n if (opts?.timeoutMs == null) {\n const current = pos.next();\n const token = eventToken(name, opts?.match, runId, current);\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as T;\n await store.putSignalWaiter({ token, runId, seq: current });\n throw new WorkflowSuspended();\n }\n const timeoutMs = opts.timeoutMs;\n const deadlineSeq = pos.next();\n const waitSeq = pos.next();\n const token = eventToken(name, opts.match, runId, waitSeq);\n const recorded = await readCheckpoint(deadlineSeq);\n const deadline = recorded?.wakeAt ?? host.clock() + timeoutMs;\n if (!recorded) {\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq: deadlineSeq,\n name: `timeout:event:${name}`,\n kind: 'sleep',\n wakeAt: deadline,\n }),\n );\n }\n const waited = await readCheckpoint(waitSeq);\n if (waited && waited.status === 'completed') return waited.output as T;\n if (host.clock() >= deadline) {\n await store.takeSignalWaiter(token).catch(() => undefined);\n throw new SignalTimeoutError(`event:${name}`, timeoutMs);\n }\n await store.putSignalWaiter({ token, runId, seq: waitSeq });\n throw new WorkflowSuspended(deadline);\n };\n\n // An external task = a checkpointed dispatch + a wait for its async-completion `Completion`\n // (delivered by engine.completeTask/failTask). The whole \"fire at a foreign system, suspend,\n // resume when it reports back\" pattern as one call.\n const task = async <T>(\n name: string,\n dispatch: () => Promise<void>,\n options?: StepOptions,\n ): Promise<T> => {\n await step(`task:dispatch:${name}`, dispatch, options);\n return unwrapCompletion<T>(await waitForSignal(`task:${runId}:${name}`), `task \"${name}\"`);\n };\n\n // Child workflow (await result): start it once, then suspend on a `child:<id>` waiter the child\n // signals on its terminal state (see engine.notifyParent).\n const child = async <T>(\n workflow: WorkflowRef,\n input: unknown,\n options?: string | ChildCallOptions,\n ): Promise<T> => {\n const { childId, priority } = normalizeChildOptions(options);\n const current = pos.next();\n const id = childId ?? `${runId}.child.${current}`;\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') {\n return unwrapCompletion<T>(existing.output, `child \"${id}\"`);\n }\n await store.putSignalWaiter({ token: `child:${id}`, runId, seq: current });\n if (!(await store.getRun(id))) host.startChild(workflowName(workflow), input, id, priority);\n // Make the awaited child visible in the parent's timeline WHILE it runs: a `running` placeholder\n // at this seq with the same `signal:child:<id>` name the signal resolution later overwrites as\n // `completed`. So the dashboard shows the child node (and can inline-expand it) live, instead of\n // it appearing only when it finishes. Written once (skipped on replay, where `existing` is set);\n // `running` is ignored by replay history, so it never short-circuits determinism.\n if (!existing) {\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq: current,\n name: `signal:child:${id}`,\n kind: 'signal',\n status: 'running',\n }),\n );\n }\n throw new WorkflowSuspended();\n };\n\n // Parallel child workflows (wait-all): dispatch N children CONCURRENTLY and wait for ALL their\n // outputs. Reserves a contiguous position block in list order FIRST (the determinism anchor), then\n // dispatches every not-yet-completed item and suspends once; on each child completion the parent\n // resumes and replays — completed items short-circuit, remaining ones re-register and re-suspend.\n // When all resolve, outputs are returned in INPUT order (waitAll), or a GatherError is thrown\n // carrying the per-item failures. Parity with the Python SDK's `gather_children`.\n const all = async <T = unknown>(\n workflow: WorkflowRef,\n inputs: unknown[],\n opts?: { mode?: 'waitAll' | 'failFast' },\n ): Promise<T[]> => {\n // Empty: reserve no positions and produce no side effects (degenerate identity).\n if (inputs.length === 0) return [];\n const mode = opts?.mode ?? 'waitAll';\n const name = workflowName(workflow);\n // Reserve the whole block in list order BEFORE any dispatch — replay re-derives identical seqs.\n const positions = inputs.map(() => pos.next());\n const group = `all:${positions[0]}`;\n const id = (i: number) => `${runId}.all.${positions[0]}.${i}`;\n const existing = await Promise.all(positions.map((seq) => readCheckpoint(seq)));\n\n // failFast: bail the moment any already-completed item is a failed Completion.\n if (mode === 'failFast') {\n for (let i = 0; i < inputs.length; i += 1) {\n const cp = existing[i];\n const c =\n cp?.status === 'completed' ? (cp.output as { ok?: boolean; error?: string }) : null;\n if (c && c.ok === false) {\n throw new GatherError(\n [{ index: i, id: id(i), error: c.error ?? 'unknown' }],\n inputs.length,\n );\n }\n }\n }\n\n // Dispatch every item not yet completed in history; write its running placeholder once.\n let pending = false;\n for (let i = 0; i < inputs.length; i += 1) {\n const cp = existing[i];\n if (cp?.status === 'completed') continue;\n pending = true;\n const seq = positions[i] as number;\n const childId = id(i);\n await store.putSignalWaiter({ token: `child:${childId}`, runId, seq });\n if (!(await store.getRun(childId))) host.startChild(name, inputs[i], childId);\n if (!cp) {\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq,\n name: `signal:child:${childId}`,\n kind: 'signal',\n status: 'running',\n parallelGroup: group,\n }),\n );\n }\n }\n // Any item still outstanding → suspend once; the resume replays this whole block.\n if (pending) throw new WorkflowSuspended();\n\n // All resolved: build outputs in INPUT order, aggregating any failures.\n const outputs: T[] = [];\n const failures: { index: number; id: string; error: string }[] = [];\n for (let i = 0; i < inputs.length; i += 1) {\n const c = existing[i]?.output as { ok?: boolean; value?: T; error?: string } | null;\n if (c && typeof c === 'object' && 'ok' in c && c.ok === false) {\n failures.push({ index: i, id: id(i), error: c.error ?? 'unknown' });\n outputs.push(undefined as T);\n } else {\n outputs.push((c as { value?: T } | null)?.value as T);\n }\n }\n if (failures.length > 0) throw new GatherError(failures, inputs.length);\n return outputs;\n };\n\n // Child workflow (fire-and-forget): dispatch it once and return its id WITHOUT suspending. The\n // start is checkpointed at this position so replay returns the same id without re-dispatching, and\n // is idempotent by id, so `child(..., sameId)` later joins the same run rather than starting a new\n // one (start + join scatter-gather).\n const startChild = async (\n workflow: WorkflowRef,\n input: unknown,\n options?: string | ChildCallOptions,\n ): Promise<string> => {\n const { childId, priority } = normalizeChildOptions(options);\n const current = pos.next();\n const id = childId ?? `${runId}.child.${current}`;\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as string;\n if (!(await store.getRun(id))) host.startChild(workflowName(workflow), input, id, priority);\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name: `spawn:${id}`, kind: 'local', output: id }),\n );\n return id;\n };\n\n // Call a durable entity op and await its result: register a reply waiter at this position, dispatch\n // the op with the reply token, and suspend until the entity signals the result back (checkpointed,\n // so replay returns it without re-dispatching).\n const callEntity = async <R>(\n name: string,\n key: string,\n op: string,\n arg?: unknown,\n ): Promise<R> => {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as R;\n const reply = `entityreply:${runId}:${current}`;\n await store.putSignalWaiter({ token: reply, runId, seq: current });\n host.signalEntity?.(name, key, op, arg, reply);\n throw new WorkflowSuspended();\n };\n\n // Send a durable entity op without awaiting a result — dispatched once (checkpointed, replay-safe).\n const signalEntity = async (\n name: string,\n key: string,\n op: string,\n arg?: unknown,\n ): Promise<void> => {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return;\n host.signalEntity?.(name, key, op, arg);\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name: `entitysig:${name}:${key}`, kind: 'local' }),\n );\n };\n\n // A breakpoint = a visible `pending` checkpoint + a signal waiter the dashboard resumes via\n // `engine.continue`. Reuses the signal machinery, so resume overwrites the pending checkpoint\n // with a completed one and the run replays past it.\n const breakpoint = async (label?: string): Promise<void> => {\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return;\n if (!existing) {\n await writeCheckpoint(\n instantCheckpoint({\n runId,\n seq: current,\n name: label ? `breakpoint:${label}` : 'breakpoint',\n kind: 'signal',\n status: 'pending',\n }),\n );\n await store.putSignalWaiter({ token: breakpointToken(runId, current), runId, seq: current });\n }\n throw new WorkflowSuspended();\n };\n\n // Guard an in-place change: a fresh run records a `patch:<id>` marker here and takes the new\n // branch; a run recorded under the OLD code finds a real step at this position instead, so we\n // rewind the logical position (the marker is transparent to it) and return false — its replay\n // reads that old step next and follows the old branch. No position shift → no corruption.\n const patched = async (id: string): Promise<boolean> => {\n const marker = `patch:${id}`;\n const current = pos.next();\n const existing = await readCheckpoint(current);\n if (existing) {\n if (existing.name === marker) return true;\n if (existing.name.startsWith('patch:')) {\n throw new NonDeterminismError(runId, current, marker, existing.name);\n }\n pos.rewind(); // not a marker: an old run's step lives here — give the position back to it\n return false;\n }\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name: marker, kind: 'local', output: true }),\n );\n return true;\n };\n\n // An update point: suspend on a run-scoped `update:<runId>:<name>` token that engine.update\n // delivers to (after its validator passes). Reuses the signal machinery; run-scoped like task/child.\n const onUpdate = <T>(name: string, opts?: { timeoutMs?: number }): Promise<T> =>\n waitForSignal<T>(`update:${runId}:${name}`, opts);\n\n // A queryable named value: a checkpoint whose `name` is `event:<key>`, so the latest value for a\n // key is just the highest-seq such checkpoint (read by engine.getEvent). Replay-idempotent.\n const setEvent = async (key: string, value: unknown): Promise<void> => {\n const current = pos.next();\n const name = `event:${key}`;\n const existing = await readCheckpoint(current);\n if (existing && existing.name !== name) {\n throw new NonDeterminismError(runId, current, name, existing.name);\n }\n if (existing && existing.status === 'completed') return; // replay: already published\n await writeCheckpoint(\n instantCheckpoint({ runId, seq: current, name, kind: 'local', output: value }),\n );\n };\n\n // A durable webhook reserves a logical position NOW to mint a stable token, so the url can be\n // handed to a third party before `wait()` suspends. `wait()` then parks on that same position\n // until the callback lands as engine.signal(token, body) — single position, replay-safe.\n const webhook = <T>(): DurableWebhook<T> => {\n const current = pos.next();\n const token = `wh:${runId}:${current}`;\n const wait = async (): Promise<T> => {\n const existing = await readCheckpoint(current);\n if (existing && existing.status === 'completed') return existing.output as T;\n await store.putSignalWaiter({ token, runId, seq: current });\n throw new WorkflowSuspended();\n };\n return { token, url: host.webhookUrl?.(token), wait };\n };\n\n // Deterministic non-deterministic sources: each is a checkpointed local step, so the value is\n // captured on the first run and replayed verbatim (a raw Date.now()/Math.random() inside a\n // workflow would differ across replays and corrupt the run).\n const now = () => step('now', async () => host.clock());\n const random = () => step('random', async () => Math.random());\n const uuid = () => step('uuid', async () => globalThis.crypto.randomUUID());\n\n return {\n runId,\n step,\n transaction,\n callEntity,\n signalEntity,\n sleep,\n sleepUntil,\n continueAsNew,\n waitForSignal,\n waitForEvent,\n task,\n child,\n all,\n startChild,\n breakpoint,\n webhook,\n setEvent,\n onUpdate,\n patched,\n now,\n random,\n uuid,\n call: (remote, input, opts) =>\n host.callRemote(runId, pos.next(), remote, input, opts?.queue, opts?.transport, {\n priority: opts?.priority,\n fairnessKey: opts?.fairnessKey,\n }),\n };\n}\n","import { type AdmissionBackend, InMemoryAdmissionBackend } from './admission';\nimport { backoffDelay } from './backoff';\nimport { instantCheckpoint, stepCheckpoint } from './checkpoints';\nimport { type Completion } from './completion';\nimport { parseDuration } from './duration';\nimport { Entities, type EntityConfig } from './entities';\nimport {\n ContinueAsNew,\n FatalError,\n NonDeterminismError,\n RemoteStepTimeout,\n RemoteWorkflowTimeout,\n SignalTimeoutError,\n WorkflowSuspended,\n} from './errors';\nimport { EventAccumulators, type EventBatchConfig } from './event-accumulators';\nimport { eventMatchOf, eventMatches, eventPrefix } from './events';\nimport type {\n ControlPlane,\n EngineEvent,\n EngineListener,\n GroupHealth,\n NamedTransport,\n RemoteStepDef,\n RemoteTask,\n RunDispatcher,\n RunQuery,\n RunResult,\n RunStatus,\n SearchAttributes,\n StateStore,\n StepCheckpoint,\n StepError,\n StepEvent,\n StepInterceptor,\n StepInvocation,\n StepKind,\n StepResult,\n Transport,\n UpdateResult,\n UpdateValidator,\n WorkflowCommand,\n WorkflowCtx,\n WorkflowDecision,\n WorkflowExecutor,\n WorkflowRun,\n WorkflowStepEvent,\n} from './interfaces';\nimport type { HistoryEvent } from './interfaces';\nimport { breakpointToken, stepId } from './protocol';\nimport type { QueueConfig } from './queue';\nimport { SingletonGate } from './singleton-gate';\nimport { TransportPool } from './transport-pool';\nimport {\n type Compensation,\n type CtxHost,\n type StepRecord,\n createWorkflowCtx,\n} from './workflow-ctx';\nimport {\n type WorkflowClass,\n type WorkflowInputOf,\n type WorkflowRef,\n workflowName,\n} from './workflow-ref';\n\ntype WorkflowFn = (ctx: WorkflowCtx, input: unknown) => Promise<unknown>;\n\n/** Options for {@link WorkflowEngine.start}. */\nexport interface StartOptions {\n /** Run-scoped tags, merged with the workflow's static `@Workflow({ tags })` onto the run. */\n tags?: string[] | undefined;\n /** Typed, queryable run data stamped on the run (e.g. `{ amount: 200, tier: 'pro' }`). */\n searchAttributes?: SearchAttributes | undefined;\n /**\n * Dispatch priority for a remote run — stamped on the run and carried onto every {@link WorkflowTask}\n * the engine dispatches to advance it. Higher wins; absent = unprioritised. See {@link WorkflowRun.priority}.\n */\n priority?: number | undefined;\n}\n\n/**\n * Serialize runs of a workflow that share a key — a durable, FIFO mutex (e.g. one pipeline per base).\n * Excess runs are admitted in creation order, `limit` at a time; the rest wait (suspended) and retry\n * admission on a timer until a slot frees. Race-free on a consistent store (admission order is the\n * same `(createdAt, id)` view for every instance).\n */\nexport interface SingletonConfig {\n /** Derive the serialization key from the workflow input. */\n key: (input: unknown) => string;\n /** Max concurrent runs sharing the key. Default 1 (a mutex). */\n limit?: number;\n /**\n * Max GATED (waiting-for-admission) runs allowed to queue behind the `limit` in-flight ones. When\n * set, `start` rejects with {@link SingletonQueueFullError} once in-flight + gated reaches\n * `limit + maxQueueDepth` — back-pressure against an unbounded same-key backlog. Omit for the\n * default unbounded queue. Counts `pending`/`running`/`suspended` runs sharing the key.\n */\n maxQueueDepth?: number;\n}\n\n/** Union of a workflow's static tags and a run's start-time tags, de-duplicated, or undefined if none. */\nfunction mergeTags(staticTags?: string[], runTags?: string[]): string[] | undefined {\n if (!staticTags?.length && !runTags?.length) return undefined;\n return [...new Set([...(staticTags ?? []), ...(runTags ?? [])])];\n}\n\n/** A breakpoint checkpoint's `name` is `breakpoint` (or `breakpoint:<label>`). This name — not the\n * reused `signal` kind — is the explicit marker the dashboard and `continue()` detect it by. */\nconst BREAKPOINT = 'breakpoint';\nconst isBreakpoint = (cp: { status: string; name: string }): boolean =>\n cp.status === 'pending' && cp.name.startsWith(BREAKPOINT);\n\ninterface RegisteredWorkflow {\n name: string;\n version: string;\n fn: WorkflowFn;\n /** Static `@Workflow({ tags })` — merged with per-run tags onto each run at start. */\n tags?: string[] | undefined;\n /** Per-key serialization (a durable mutex). See {@link SingletonConfig}. */\n singleton?: SingletonConfig | undefined;\n /** Max wall-clock lifetime (ms) before a run is cancelled by `sweepTimeouts`. */\n executionTimeoutMs?: number | undefined;\n /** Validate the input at start; throw to reject before a run is created. Validator-agnostic. */\n validateInput?: ((input: unknown) => void | Promise<void>) | undefined;\n /** Event names that start a fresh run of this workflow when published. See `publishEvent`. */\n onEvent?: string[] | undefined;\n /** Coalesce `onEvent` triggers: debounce (fire once it's quiet) or batch (fire on size/window). */\n eventBatch?: EventBatchConfig | undefined;\n /** Set for a workflow authored in another SDK (e.g. Python): the engine advances it by dispatching\n * workflow tasks to `executor` instead of running `fn` in-process. See {@link WorkflowExecutor}. */\n remote?: { group: string; executor: WorkflowExecutor };\n}\n\nconst versionKey = (name: string, version: string): string => `${name}@${version}`;\n\n/** The id for the next continuation of a run: `r` → `r~1` → `r~2` … (stable, traceable lineage). */\nfunction nextContinuationId(runId: string): string {\n const m = runId.match(/^(.*)~(\\d+)$/);\n return m ? `${m[1]}~${Number(m[2]) + 1}` : `${runId}~1`;\n}\n\n/** True when version `a` is newer than `b` (numeric when both parse as numbers, else natural sort). */\nfunction isNewerVersion(a: string, b: string): boolean {\n const na = Number(a);\n const nb = Number(b);\n if (!Number.isNaN(na) && !Number.isNaN(nb)) return na > nb;\n return a.localeCompare(b, undefined, { numeric: true }) > 0;\n}\n\n/** What a remote worker hands back: the output plus when it actually began (for queue-wait timing). */\ninterface RemoteResolution {\n output: unknown;\n startedAt?: number | undefined;\n events?: StepEvent[] | undefined;\n}\n\ninterface PendingRemote {\n resolve: (result: RemoteResolution) => void;\n reject: (error: Error) => void;\n}\n\n/** A terminal/suspended transition handed to {@link WorkflowEngine.settleRun}. */\ntype RunOutcome =\n | { kind: 'completed'; output: unknown }\n | { kind: 'failed'; error: StepError }\n | { kind: 'suspended'; wakeAt?: number | undefined };\n\nexport interface WorkflowEngineDeps {\n store: StateStore;\n /** A single task transport. Shorthand for a one-entry `transports` pool (id `default`). */\n transport?: Transport | undefined;\n /**\n * An ordered pool of named transports. The engine dispatches on the first and fails over to the\n * next on a dispatch error; a step pins one via `ctx.call(step, input, { transport: id })`. Use\n * this instead of `transport` for failover / multi-broker setups.\n */\n transports?: NamedTransport[] | undefined;\n /**\n * Cross-instance broadcast pub/sub for lifecycle events + cancellation (see {@link ControlPlane}).\n * Separate from the task `transport`; omit for a single-instance / local-only setup. A transport\n * that can also broadcast may be passed here as well.\n */\n controlPlane?: ControlPlane | undefined;\n /** Epoch-ms clock; injectable for tests. Defaults to `Date.now`. */\n clock?: (() => number) | undefined;\n /**\n * Flow-control admission backend for `ctx.call(step, input, { queue })`. Defaults to an in-process\n * {@link InMemoryAdmissionBackend} (per-instance caps). Inject a store/Redis-backed backend to make\n * concurrency / rate-limit / ordering GLOBAL across engine replicas.\n */\n admission?: AdmissionBackend | undefined;\n /** Unique id for this engine instance, used for recovery leases. Defaults to a random id. */\n instanceId?: string | undefined;\n /** Recovery lease duration in ms — how long this instance owns a run it picked up. Default 30s. */\n leaseMs?: number | undefined;\n /**\n * Cap how many times crash-recovery may pick up the same still-`running` run before giving up and\n * moving it to the `dead` dead-letter state (a poison pill that crashes the process every boot).\n * Omit for unlimited (the default — recovery always retries).\n */\n maxRecoveryAttempts?: number | undefined;\n /**\n * Build the public callback URL for a `ctx.webhook()` token (e.g.\n * ``(t) => `https://api.example.com/durable/webhooks/${t}` ``). Populates\n * {@link DurableWebhook.url}. Omit if you build URLs yourself from the token.\n */\n webhookUrl?: ((token: string) => string) | undefined;\n /**\n * Provide the current W3C `traceparent` to stamp on each dispatched {@link RemoteTask}, so a\n * worker (including the Python SDK) continues the distributed trace. Keep core OTel-free: supply\n * `otelTraceparent` from `@dudousxd/nestjs-durable-otel`, or your own context reader. Omit to send none.\n */\n traceparent?: (() => string | undefined) | undefined;\n /**\n * Provide an opaque context carrier (tenant / user / correlation ids) to attach to each dispatched\n * {@link RemoteTask} as its `context`, so a worker (including the Python SDK) re-exposes it to the\n * step handler — cross-process propagation alongside the {@link traceparent}. Keep core dependency-free:\n * supply this from `@dudousxd/nestjs-context` or your own request-scoped reader. The engine never\n * inspects the returned object's shape. Omit to send none.\n *\n * Re-evaluated at each (re)dispatch — including a retry or a resume that the engine drives AFTER a\n * crash/scale-down, which runs OUTSIDE the originating request scope. On such a path this provider\n * may return empty or stale values (the request-scoped tenant/user is gone). Treat the carrier as\n * best-effort correlation/propagation metadata only — do NOT treat it as an authorization boundary.\n */\n context?: (() => Record<string, unknown> | undefined) | undefined;\n /**\n * Re-hydrate the originating context around a LOCAL step body, so a `@DurableStep` reader sees the\n * tenant / user / correlation ids that were live when the run was started — even on a path the\n * engine drives outside the originating request scope (a resume after crash/scale-down, a timer).\n * Given the carrier produced by {@link context} (may be empty/undefined) and the step body `fn`, it\n * runs `fn` with that context ambiently established (e.g. inside `@dudousxd/nestjs-context`'s ALS)\n * and returns its result. Keep core dependency-free: supply this from the nestjs wiring (which owns\n * nestjs-context) or your own ALS bridge. The handler signature is unchanged — re-hydration is\n * ambient. Default: passthrough (`(_, fn) => fn()`), so behavior is byte-identical when unset.\n */\n rehydrate?: (<T>(carrier: Record<string, unknown> | undefined, fn: () => T) => T) | undefined;\n /**\n * Attempts for each saga compensation when the run fails (a transient undo — e.g. a refund API\n * hiccup — gets another try). Default 1 (no retry). Compensations must be idempotent.\n */\n compensationRetries?: number | undefined;\n /**\n * Persist a `running` checkpoint when a local step's body begins, so an in-flight step shows up\n * in the dashboard (and a fresh page load / REST query) the moment it starts — not only once it\n * completes. The `step.started` lifecycle event is emitted either way (the live SSE view always\n * sees the start); this flag only controls the extra checkpoint write. Default `true`. Set\n * `false` on hot paths with many short local steps to halve their checkpoint writes — you keep\n * the live event but lose reload-survivable in-flight visibility.\n */\n trackStepStart?: boolean | undefined;\n /**\n * Where a freshly-`start`ed run executes (see {@link RunDispatcher}). Defaults to in-process: the\n * run executes on this instance asynchronously (a microtask), so `start` returns without blocking.\n * Pass a no-op dispatcher on a caller that must NOT run workflows (e.g. an API/dashboard pod), and\n * run `runPending` on a worker pod to pick those up; or a broker-backed one for a worker pool.\n */\n runDispatcher?: RunDispatcher | undefined;\n}\n\n/**\n * The orchestrator. Owns workflow state and replays runs deterministically: each step's\n * result is checkpointed, so on resume a completed step returns its saved output instead of\n * re-executing. Remote steps are dispatched over the Transport; their results checkpoint the\n * same way local steps do.\n */\nexport class WorkflowEngine {\n private readonly store: StateStore;\n /** Ordered transport pool (dispatch + failover). Empty = no remote steps. */\n private readonly pool: TransportPool;\n private readonly controlPlane?: ControlPlane | undefined;\n private readonly clock: () => number;\n private readonly instanceId: string;\n private readonly leaseMs: number;\n private readonly maxRecoveryAttempts?: number | undefined;\n private readonly webhookUrl?: ((token: string) => string) | undefined;\n private readonly traceparent?: (() => string | undefined) | undefined;\n private readonly context?: (() => Record<string, unknown> | undefined) | undefined;\n /** Establish the originating context ambiently around a local step body (see {@link WorkflowEngineDeps.rehydrate}). Default passthrough. */\n private readonly rehydrate: <T>(carrier: Record<string, unknown> | undefined, fn: () => T) => T;\n private readonly compensationRetries: number;\n /** Persist a `running` checkpoint at the start of a local step body (see {@link WorkflowEngineDeps.trackStepStart}). */\n private readonly trackStepStart: boolean;\n /** Where a freshly-started run executes — in-process by default (see {@link RunDispatcher}). */\n private readonly runDispatcher: RunDispatcher;\n\n /** Per-key serialization for singleton workflows (admission, back-pressure, notify-on-release). */\n private readonly singletons: SingletonGate;\n /** Every registered workflow, keyed by `name@version` — so old versions stay runnable. */\n private readonly workflows = new Map<string, RegisteredWorkflow>();\n /** The newest registered version per workflow name — used to `start` new runs. */\n private readonly latest = new Map<string, RegisteredWorkflow>();\n /** Event name → workflow names started when that event is published (see `onEvent`). */\n private readonly eventTriggers = new Map<string, Set<string>>();\n /** Durable-entity subsystem (registers the `__entity` runner; see `registerEntity`). */\n private readonly entities: Entities;\n /** Event debounce/batch accumulators (register the `__evt_*` runners; see `accumulators.route`). */\n private readonly accumulators: EventAccumulators;\n /** In-flight remote steps awaiting a worker result, keyed by stepId. */\n private readonly pending = new Map<string, PendingRemote>();\n /** Per-step \"reset the liveness timer\" callbacks, called when a heartbeat arrives. */\n private readonly heartbeatResets = new Map<string, () => void>();\n private readonly listeners = new Set<EngineListener>();\n /** Step interceptors (onion middleware around real local-step execution), first = outermost. */\n private readonly interceptors: StepInterceptor[] = [];\n /** Callbacks notified (on any instance) when a run is cancelled — for cooperative cancellation. */\n private readonly cancelListeners = new Set<(runId: string) => void>();\n /** Callbacks notified when a run is enqueued elsewhere — for low-latency cross-pod dispatch. */\n private readonly enqueuedListeners = new Set<(runId: string) => void>();\n /** Notified when a run is dead-lettered (moved to `dead`) — a hook for a DLQ handler. */\n private readonly deadListeners = new Set<(run: WorkflowRun) => void>();\n /** Validators gating `engine.update`, keyed by `<workflow>:<updateName>`. */\n private readonly updateValidators = new Map<string, UpdateValidator>();\n /** Runs being cancelled WITH saga compensation — see `cancel({ compensate: true })`. */\n private readonly cancelRequested = new Set<string>();\n /** Flow-control admission backend for remote steps (see {@link registerQueue}). */\n private readonly admission: AdmissionBackend;\n /** Runs on THIS instance blocked on admission, by queue — woken early on a freed-slot signal. */\n private readonly queueWaiters = new Map<string, Set<string>>();\n /** Which queue a dispatched step took a slot from, by stepId — so the result can release it. */\n private readonly stepQueue = new Map<string, string>();\n /** Executions currently in flight, so a graceful shutdown can wait for them to settle. */\n private readonly inflight = new Set<Promise<RunResult>>();\n private draining = false;\n\n constructor(deps: WorkflowEngineDeps) {\n this.store = deps.store;\n this.pool = new TransportPool(\n deps.transports ?? (deps.transport ? [{ id: 'default', transport: deps.transport }] : []),\n );\n this.controlPlane = deps.controlPlane;\n this.clock = deps.clock ?? Date.now;\n this.admission = deps.admission ?? new InMemoryAdmissionBackend(this.clock);\n // Wake this instance's admission-blocked runs the moment a slot frees anywhere in the fleet,\n // instead of waiting for their retry tick. Best-effort (the retry tick remains the guarantee).\n this.admission.onFreed?.((queue) => this.wakeQueueWaiters(queue));\n this.instanceId = deps.instanceId ?? globalThis.crypto.randomUUID();\n this.leaseMs = deps.leaseMs ?? 30_000;\n this.maxRecoveryAttempts = deps.maxRecoveryAttempts;\n this.webhookUrl = deps.webhookUrl;\n this.traceparent = deps.traceparent;\n this.context = deps.context;\n // Default passthrough: with no bridge supplied, a local step body runs exactly as before.\n this.rehydrate = deps.rehydrate ?? ((_carrier, fn) => fn());\n this.compensationRetries = Math.max(1, deps.compensationRetries ?? 1);\n this.trackStepStart = deps.trackStepStart ?? true;\n // Default: execute the run on this instance, asynchronously, so `start` never blocks on the body.\n // A failed pickup is swallowed here (the run stays `pending` for a `runPending` poll to retry);\n // run failures themselves are handled inside `execute` and surfaced as the run's `failed` state.\n this.runDispatcher = deps.runDispatcher ?? {\n dispatch: (runId) => queueMicrotask(() => void this.runOne(runId).catch(() => {})),\n };\n this.singletons = new SingletonGate({\n store: this.store,\n clock: this.clock,\n dispatch: (runId) => {\n this.runDispatcher.dispatch(runId);\n },\n configFor: (run) =>\n (\n this.workflows.get(versionKey(run.workflow, run.workflowVersion)) ??\n this.latest.get(run.workflow)\n )?.singleton,\n });\n this.pool.bind(\n async (result) => {\n // In-memory path (a `timeoutMs` step awaiting on THIS instance): resolve its pending promise.\n const waiter = this.pending.get(result.stepId);\n if (waiter) {\n this.pending.delete(result.stepId);\n if (result.status === 'completed') {\n waiter.resolve({\n output: result.output,\n startedAt: result.startedAt,\n events: result.events,\n });\n } else {\n waiter.reject(new RemoteStepError(result.error));\n }\n return;\n }\n // Durable path: no in-memory waiter (the step suspended the run, possibly on another\n // instance) → complete the checkpoint and resume the run here.\n await this.completeRemoteResult(result);\n },\n // A heartbeat for an in-flight long step resets its liveness window (see callRemote).\n async (beat) => {\n this.heartbeatResets.get(beat.stepId)?.();\n },\n // A remote workflow worker streams each local step's lifecycle (running → completed/failed) so\n // it's checkpointed live, not all-at-once when the long turn ends.\n async (event) => {\n await this.persistStepEvent(event);\n },\n );\n // Control plane: re-broadcast lifecycle events from OTHER instances to this instance's\n // subscribers (cross-pod live-tail), and act on cancellations issued elsewhere. A broker may\n // echo our own publish back — ignore those (we already handled them locally) to avoid duplicates.\n this.controlPlane?.onControl((msg) => {\n if (msg.from === this.instanceId) return;\n if (msg.kind === 'event') {\n // `at` may be a string after JSON transit (Redis) — normalize back to a Date.\n this.deliver({ ...msg.event, at: new Date(msg.event.at) });\n } else if (msg.kind === 'cancel') {\n this.notifyCancelled(msg.runId);\n } else if (msg.kind === 'enqueued') {\n // A run was enqueued on another instance — let worker subscribers pick it up immediately\n // instead of waiting for the next poll. (Self-broadcasts are already filtered above.)\n for (const fn of this.enqueuedListeners) {\n try {\n fn(msg.runId);\n } catch {\n /* an enqueue listener must not break the engine */\n }\n }\n }\n });\n this.accumulators = new EventAccumulators(this);\n this.entities = new Entities(this);\n }\n\n /**\n * Register a **durable entity** (a virtual object): a keyed actor whose `handlers` run **serialized\n * per key** over **durable state**, exactly once. Drive it with `signalEntity` (fire) /\n * `ctx.callEntity` (call + await result) and read its state with `getEntityState`. See {@link Entities}.\n */\n registerEntity<S>(name: string, config: EntityConfig<S>): void {\n this.entities.register(name, config);\n }\n\n /** Send an operation to an entity (fire-and-forget). Ordered + exactly-once per key. */\n signalEntity(name: string, key: string, op: string, arg?: unknown): Promise<void> {\n return this.entities.signal(name, key, op, arg);\n }\n\n /** Read an entity's current durable state (published after each op), or undefined if it has none yet. */\n getEntityState<S = unknown>(name: string, key: string): Promise<S | undefined> {\n return this.entities.getState<S>(name, key);\n }\n\n /**\n * Be notified when a run is enqueued on ANOTHER instance (via the control plane), so a worker can\n * pick it up at once — e.g. `engine.onEnqueued((runId) => engine.runOne(runId))`. Returns an\n * unsubscribe function. Only wire this on instances that should execute runs (workers).\n */\n onEnqueued(listener: (runId: string) => void): () => void {\n this.enqueuedListeners.add(listener);\n return () => this.enqueuedListeners.delete(listener);\n }\n\n /** Fire cooperative-cancellation listeners for `runId` (a worker bridge aborts in-flight work). */\n private notifyCancelled(runId: string): void {\n for (const fn of this.cancelListeners) {\n try {\n fn(runId);\n } catch {\n /* a cancel listener must not break the engine */\n }\n }\n }\n\n /**\n * Register a workflow version. Register multiple versions of the same name to keep in-flight\n * runs working across a breaking change: old runs resume on the version they started on, new\n * runs start on the newest registered version.\n */\n register(\n name: string,\n version: string,\n fn: WorkflowFn,\n opts?: {\n tags?: string[] | undefined;\n singleton?: SingletonConfig | undefined;\n executionTimeout?: string | number | undefined;\n validateInput?: ((input: unknown) => void | Promise<void>) | undefined;\n onEvent?: string[] | undefined;\n eventBatch?: EventBatchConfig | undefined;\n },\n ): void {\n const registered: RegisteredWorkflow = {\n name,\n version,\n fn,\n tags: opts?.tags,\n singleton: opts?.singleton,\n executionTimeoutMs:\n opts?.executionTimeout != null ? parseDuration(opts.executionTimeout) : undefined,\n validateInput: opts?.validateInput,\n onEvent: opts?.onEvent,\n eventBatch: opts?.eventBatch,\n };\n this.workflows.set(versionKey(name, version), registered);\n const current = this.latest.get(name);\n if (!current || isNewerVersion(version, current.version)) this.latest.set(name, registered);\n for (const event of opts?.onEvent ?? []) {\n const subscribers = this.eventTriggers.get(event) ?? new Set<string>();\n subscribers.add(name);\n this.eventTriggers.set(event, subscribers);\n }\n }\n\n /**\n * Register a workflow whose body runs in another SDK (e.g. Python). The engine owns the run exactly\n * as for a TS workflow — it persists checkpoints, recovers, runs timers — but advances it by handing\n * the run's history to `executor` (which dispatches a {@link WorkflowTask} to the worker) and applying\n * the {@link WorkflowDecision} the worker's replay returns. The worker never touches the store.\n */\n registerRemote(\n name: string,\n version: string,\n opts: {\n group: string;\n executor: WorkflowExecutor;\n tags?: string[];\n singleton?: SingletonConfig;\n executionTimeout?: string | number;\n validateInput?: (input: unknown) => void | Promise<void>;\n },\n ): void {\n const registered: RegisteredWorkflow = {\n name,\n version,\n // A remote workflow has no in-process body; execute() branches on `remote` before this is read.\n fn: () => {\n throw new Error(`workflow ${name} is remote — it has no in-process body`);\n },\n tags: opts.tags,\n singleton: opts.singleton,\n executionTimeoutMs:\n opts.executionTimeout != null ? parseDuration(opts.executionTimeout) : undefined,\n validateInput: opts.validateInput,\n remote: { group: opts.group, executor: opts.executor },\n };\n this.workflows.set(versionKey(name, version), registered);\n const current = this.latest.get(name);\n if (!current || isNewerVersion(version, current.version)) this.latest.set(name, registered);\n }\n\n /**\n * Register a flow-control queue referenced by `ctx.call(step, input, { queue })`. Caps concurrent\n * in-flight steps and/or the admission rate; blocked calls re-suspend and retry, so the limit is\n * durable. Per engine instance (see {@link QueueConfig}). Registering the same name replaces it.\n */\n registerQueue(config: QueueConfig): void {\n this.admission.register(config);\n }\n\n /** Subscribe to lifecycle events. Returns an unsubscribe function. */\n subscribe(listener: EngineListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Register a {@link StepInterceptor} — onion middleware run around the real execution of every\n * local `ctx.step` (timing, logging, tracing, error enrichment, context propagation). First\n * registered is outermost; interceptors fire only when a step executes, never on replay. Returns\n * an unsubscribe function.\n */\n use(interceptor: StepInterceptor): () => void {\n this.interceptors.push(interceptor);\n return () => {\n const i = this.interceptors.indexOf(interceptor);\n if (i >= 0) this.interceptors.splice(i, 1);\n };\n }\n\n /**\n * Fold the registered interceptors around a local step body (identity when there are none), then\n * run the whole thing inside the re-hydrated originating context. The carrier is read at execution\n * time from {@link context} — the SAME reader stamped on dispatched remote tasks — so a local step\n * sees the live tenant / user / trace ids ambiently (via the {@link rehydrate} bridge). Default\n * `rehydrate` is a passthrough, so this is byte-identical to a bare body call when unwired.\n */\n private interceptStep<T>(invocation: StepInvocation, body: () => Promise<T>): Promise<T> {\n const carrier = this.context?.();\n const run = (): Promise<T> => {\n if (this.interceptors.length === 0) return body();\n const chain = this.interceptors.reduceRight<() => Promise<unknown>>(\n (next, interceptor) => () => interceptor(invocation, next),\n body as () => Promise<unknown>,\n );\n return chain() as Promise<T>;\n };\n return this.rehydrate(carrier, run);\n }\n\n /**\n * Be notified when a run is cancelled — on ANY instance, via the transport control plane. A\n * worker bridge can use this for cooperative cancellation: abort the in-flight work for `runId`\n * instead of finishing it just to have the result discarded. Returns an unsubscribe function.\n */\n onCancel(listener: (runId: string) => void): () => void {\n this.cancelListeners.add(listener);\n return () => this.cancelListeners.delete(listener);\n }\n\n /**\n * Be notified when a run is **dead-lettered** — moved to `dead` after exceeding\n * `maxRecoveryAttempts`. The listener receives the dead run (status `dead`, with its error), so a\n * DLQ handler can do something other than just leaving it parked: alert, push to a real queue, or\n * start a dead-letter workflow (e.g. `engine.onDead((run) => engine.start('pipeline-dlq', run, ...))`).\n * Returns an unsubscribe function.\n */\n onDead(listener: (run: WorkflowRun) => void): () => void {\n this.deadListeners.add(listener);\n return () => this.deadListeners.delete(listener);\n }\n\n private notifyDead(run: WorkflowRun): void {\n for (const fn of this.deadListeners) {\n try {\n fn(run);\n } catch {\n /* a dead-letter handler must not break recovery */\n }\n }\n }\n\n /** Emit a locally-produced lifecycle event: deliver to subscribers AND broadcast it on the\n * control plane so other instances (e.g. a dashboard pod) can live-tail this run. */\n private emit(event: Omit<EngineEvent, 'at'>): void {\n const full: EngineEvent = { ...event, at: new Date() };\n this.deliver(full);\n if (this.controlPlane) {\n void this.controlPlane\n .publishControl({ kind: 'event', event: full, from: this.instanceId })\n .catch(() => {\n // control-plane delivery is best-effort observability; never break execution\n });\n }\n }\n\n /** Deliver an event to local subscribers only (no re-broadcast) — used for both locally-produced\n * events and ones received from the control plane, so an event shows up once on every instance. */\n private deliver(event: EngineEvent): void {\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch {\n // a misbehaving subscriber must never break workflow execution\n }\n }\n }\n\n async start<C extends WorkflowClass>(\n workflow: C,\n input: WorkflowInputOf<C>,\n runId: string,\n opts?: StartOptions,\n ): Promise<RunResult>;\n async start<TInput>(\n workflow: string,\n input: TInput,\n runId: string,\n opts?: StartOptions,\n ): Promise<RunResult>;\n async start(\n workflow: WorkflowRef,\n input: unknown,\n runId: string,\n opts?: StartOptions,\n ): Promise<RunResult> {\n const name = workflowName(workflow);\n const registered = this.latest.get(name);\n if (!registered) throw new Error(`workflow ${name} is not registered`);\n // Validate the input up front — a bad payload is rejected before any run is created.\n await registered.validateInput?.(input);\n // Idempotent by run id: a redelivered trigger (at-least-once queues) or a scheduler re-tick for\n // the same id is a no-op, returning the existing run's state instead of starting a duplicate.\n const prior = await this.store.getRun(runId);\n if (prior) {\n return { runId, status: prior.status, output: prior.output, error: prior.error };\n }\n const now = new Date();\n // A singleton workflow stamps a `singleton:<key>` tag so the admission gate (in execute) can find\n // the other in-flight runs sharing the key via a tag+status query.\n const tags = mergeTags(\n registered.tags,\n registered.singleton\n ? [...(opts?.tags ?? []), this.singletons.tag(registered.singleton, input)]\n : opts?.tags,\n );\n // Singleton back-pressure: reject a start that would grow the same-key backlog past\n // `limit + maxQueueDepth` (no-op when no maxQueueDepth is configured).\n if (registered.singleton) {\n await this.singletons.assertCapacity(name, registered.singleton, input);\n }\n const run: WorkflowRun = {\n id: runId,\n workflow: name,\n workflowVersion: registered.version,\n status: 'pending',\n input,\n tags,\n searchAttributes: opts?.searchAttributes,\n priority: opts?.priority,\n createdAt: now,\n updatedAt: now,\n };\n await this.store.createRun(run);\n // The run is durably enqueued; a dispatcher (in-process by default) executes it — `start` does\n // NOT run the body inline. Await the terminal/suspended state with `waitForRun(runId)` if needed.\n await this.runDispatcher.dispatch(runId);\n // Nudge worker instances to pick it up now instead of on their next poll (no-op without a control\n // plane; self-receipt is filtered, so it only helps OTHER pods — e.g. an API pod's enqueue).\n if (this.controlPlane) {\n void this.controlPlane\n .publishControl({ kind: 'enqueued', runId, from: this.instanceId })\n .catch(() => undefined);\n }\n return { runId, status: 'pending' };\n }\n\n /** Read a run's current persisted state (or null if unknown). A thin pass-through to the store. */\n getRun(runId: string): Promise<WorkflowRun | null> {\n return this.store.getRun(runId);\n }\n\n async resume(runId: string): Promise<RunResult> {\n const run = await this.store.getRun(runId);\n if (!run) throw new Error(`run ${runId} not found`);\n // A definitively-finished run must not be re-executed (e.g. a worker result landing after the\n // run was cancelled, or a duplicate resume) — that would replay the body and clobber the\n // terminal state. `failed` is intentionally NOT terminal here: retry resumes a failed run.\n if (run.status === 'cancelled' || run.status === 'completed' || run.status === 'dead') {\n return { runId, status: run.status, output: run.output, error: run.error };\n }\n // Pin to the version the run STARTED on — replay is positional, so running a changed\n // workflow body against old checkpoints would corrupt the run.\n const registered = this.workflows.get(versionKey(run.workflow, run.workflowVersion));\n if (!registered) {\n throw new Error(\n `workflow ${run.workflow}@${run.workflowVersion} is not registered — keep the prior version deployed so in-flight runs can drain (skew protection)`,\n );\n }\n return this.track(this.execute(run, registered.fn));\n }\n\n /** Track an in-flight execution so {@link drain} can wait for it. */\n private track(p: Promise<RunResult>): Promise<RunResult> {\n this.inflight.add(p);\n void p.finally(() => this.inflight.delete(p));\n return p;\n }\n\n /**\n * Graceful shutdown: stop picking up new runs (recovery/timer become no-ops) and wait for\n * in-flight executions to settle, up to `timeoutMs`. Call from your app's shutdown hook so a\n * deploy hands off cleanly instead of leaving runs to the lease timeout.\n */\n async drain(timeoutMs = 10_000): Promise<void> {\n this.draining = true;\n if (this.inflight.size === 0) return;\n const timer = new Promise<void>((resolve) => {\n const t = setTimeout(resolve, timeoutMs);\n (t as { unref?: () => void }).unref?.();\n });\n await Promise.race([Promise.allSettled([...this.inflight]), timer]);\n }\n\n /**\n * Cancel in-flight runs that have outlived their workflow's `executionTimeout`. Call it from the\n * timer poller alongside {@link resumeDueTimers}. A timed-out run is moved to `cancelled` with an\n * `execution_timeout` error (terminal, so a late step result can't resurrect it).\n */\n async sweepTimeouts(now: number = this.clock()): Promise<void> {\n for (const reg of new Set(this.latest.values())) {\n if (reg.executionTimeoutMs == null) continue;\n const deadline = now - reg.executionTimeoutMs;\n const inflight = [\n ...(await this.store.listRuns({ workflow: reg.name, status: 'running' })),\n ...(await this.store.listRuns({ workflow: reg.name, status: 'suspended' })),\n ];\n for (const run of inflight) {\n if (run.createdAt.getTime() > deadline) continue;\n const error = { message: 'execution timeout', code: 'execution_timeout' };\n await this.store.updateRun(run.id, { status: 'cancelled', error, updatedAt: new Date() });\n this.emit({ type: 'run.failed', runId: run.id, workflow: run.workflow, error });\n }\n }\n }\n\n /**\n * Resume every run left incomplete by a crash or deploy. Called on boot. Completed steps\n * replay from their checkpoints, so only the work that had not finished runs again.\n */\n async recoverIncomplete(nowMs: number = this.clock()): Promise<RunResult[]> {\n if (this.draining) return [];\n const results: RunResult[] = [];\n for (const run of await this.store.listIncompleteRuns()) {\n // A live worker renews its lease, so an acquirable lease means the run is genuinely orphaned\n // (its worker crashed). Skip the ones still owned.\n const acquired = await this.store.tryLockRun(\n run.id,\n this.instanceId,\n nowMs + this.leaseMs,\n nowMs,\n );\n if (!acquired) continue;\n // Count the attempt / dead-letter a poison pill past maxRecoveryAttempts.\n const settled = await this.countRecovery(run);\n if (settled) {\n results.push(settled);\n continue;\n }\n // Re-enqueue rather than resume inline: recovery must NOT block (boot, or a poll tick) on a\n // long workflow step. A dispatcher/worker re-runs it, replaying its checkpoints.\n await this.store.releaseRunLock(run.id);\n await this.store.updateRun(run.id, { status: 'pending', updatedAt: new Date() });\n await this.runDispatcher.dispatch(run.id);\n results.push({ runId: run.id, status: 'pending' });\n }\n return results;\n }\n\n /**\n * Per-recovery bookkeeping (called once the lease is held): count the attempt, or — past\n * `maxRecoveryAttempts` — move a poison pill to the `dead` dead-letter state. Returns a terminal\n * result to skip the resume, or `undefined` to proceed.\n */\n private async countRecovery(run: WorkflowRun): Promise<RunResult | undefined> {\n const attempts = (run.recoveryAttempts ?? 0) + 1;\n if (this.maxRecoveryAttempts != null && attempts > this.maxRecoveryAttempts) {\n const error = {\n message: `run exceeded maxRecoveryAttempts (${this.maxRecoveryAttempts}) — moved to dead-letter`,\n code: 'max_recovery_attempts',\n };\n await this.store.updateRun(run.id, { status: 'dead', error, updatedAt: new Date() });\n await this.store.releaseRunLock(run.id);\n this.emit({ type: 'run.failed', runId: run.id, workflow: run.workflow, error });\n this.notifyDead({ ...run, status: 'dead', error, recoveryAttempts: attempts });\n return { runId: run.id, status: 'dead', error };\n }\n // Count BEFORE resuming, so a crash mid-resume still advances the counter.\n await this.store.updateRun(run.id, { recoveryAttempts: attempts, updatedAt: new Date() });\n return undefined;\n }\n\n /**\n * Resume every suspended run whose durable timer is due. Call periodically (a poller) and on\n * boot. A run still not due re-suspends cheaply without running new work.\n */\n async resumeDueTimers(nowMs: number = this.clock()): Promise<RunResult[]> {\n return this.resumeLeased(await this.store.listDueTimers(nowMs), nowMs);\n }\n\n /**\n * Lease and execute one run by id — the worker side of dispatch. Acquires the recovery lease (so\n * exactly one instance runs it), then resumes the body. Returns the result, or null if another\n * instance holds the lease or the engine is draining. The default in-process dispatcher calls this;\n * a broker-backed worker calls it per consumed run id.\n */\n async runOne(runId: string): Promise<RunResult | null> {\n if (this.draining) return null;\n const nowMs = this.clock();\n const acquired = await this.store.tryLockRun(\n runId,\n this.instanceId,\n nowMs + this.leaseMs,\n nowMs,\n );\n if (!acquired) return null;\n return this.resume(runId);\n }\n\n /**\n * Re-enqueue a run for a worker to (re-)execute — the dispatch-model **retry**. Sets it back to\n * `pending`, clears any stale lease, and dispatches; a worker resumes it (replaying its checkpoints,\n * re-attempting the failed step). Returns the enqueued state immediately — never runs the body\n * inline — or null if the run is unknown. The dashboard \"retry\" goes through here so it can't block\n * the HTTP request on workflow execution.\n */\n async requeue(runId: string): Promise<RunResult | null> {\n const run = await this.store.getRun(runId);\n if (!run) return null;\n await this.store.releaseRunLock(runId);\n await this.store.updateRun(runId, { status: 'pending', updatedAt: new Date() });\n await this.runDispatcher.dispatch(runId);\n return { runId, status: 'pending' };\n }\n\n /**\n * **Fix-and-replay**: re-run a run (typically a `dead`/`failed` one) with a corrected `input`, as a\n * fresh run with clean history. It's a NEW run — `newRunId` defaults to `<runId>~retry~<uuid>` — so\n * the original stays inspectable. Returns the new run's id, or null if `runId` is unknown.\n */\n async retryWithInput(\n runId: string,\n input: unknown,\n newRunId?: string,\n ): Promise<{ runId: string } | null> {\n const run = await this.store.getRun(runId);\n if (!run) return null;\n const id = newRunId ?? `${runId}~retry~${globalThis.crypto.randomUUID().slice(0, 8)}`;\n await this.start(run.workflow, input, id, { tags: run.tags });\n return { runId: id };\n }\n\n /**\n * Pick up and execute every `pending` run — the poll-based side of dispatch for a worker pod with\n * no broker. Runs enqueued by other pods (or by a caller using a no-op dispatcher) sit `pending`\n * in the store until polled; leasing ensures exactly one pod runs each. Call periodically alongside\n * {@link resumeDueTimers}.\n */\n async runPending(nowMs: number = this.clock()): Promise<RunResult[]> {\n // Oldest-first (FIFO), capped per call so a backlog drains over several polls without one sweep\n // fetching unboundedly. A run not picked up this tick is picked up the next.\n return this.resumeLeased(await this.store.listPendingRuns(100), nowMs);\n }\n\n /**\n * Resolve once `runId` reaches a settled state — terminal (completed/failed/cancelled/dead) or\n * suspended (handed off to a timer/signal/event). The async counterpart to dispatch: pair it with\n * `start` when a call site needs the outcome — `await start(...); const r = await waitForRun(id)`.\n */\n waitForRun(runId: string, opts?: { timeoutMs?: number }): Promise<RunResult> {\n const isSettled = (s: RunStatus): boolean => s !== 'pending' && s !== 'running';\n const toResult = (run: WorkflowRun): RunResult => ({\n runId,\n status: run.status,\n output: run.output,\n error: run.error,\n });\n return new Promise<RunResult>((resolve, reject) => {\n let done = false;\n let off: () => void = () => {};\n const timer =\n opts?.timeoutMs != null\n ? setTimeout(() => {\n if (done) return;\n done = true;\n off();\n reject(new Error(`waitForRun(${runId}) timed out after ${opts.timeoutMs}ms`));\n }, opts.timeoutMs)\n : undefined;\n const finish = (run: WorkflowRun): void => {\n if (done) return;\n done = true;\n if (timer) clearTimeout(timer);\n off();\n resolve(toResult(run));\n };\n const check = (): void => {\n void this.store.getRun(runId).then((run) => {\n if (run && isSettled(run.status)) finish(run);\n });\n };\n // React only to this run's settling events (not its every step event), and subscribe BEFORE the\n // initial read so a run that settles in between isn't missed.\n off = this.subscribe((ev) => {\n if (\n ev.runId === runId &&\n (ev.type === 'run.completed' || ev.type === 'run.failed' || ev.type === 'run.suspended')\n ) {\n check();\n }\n });\n check();\n });\n }\n\n /**\n * Resume each run only if this instance can acquire its recovery lease — so when several\n * replicas recover or poll at once, each run is picked up by exactly one of them.\n */\n private async resumeLeased(\n runs: WorkflowRun[],\n nowMs: number = this.clock(),\n onLocked?: (run: WorkflowRun) => Promise<RunResult | undefined>,\n ): Promise<RunResult[]> {\n if (this.draining) return []; // shutting down — don't pick up new runs\n const results: RunResult[] = [];\n for (const run of runs) {\n const acquired = await this.store.tryLockRun(\n run.id,\n this.instanceId,\n nowMs + this.leaseMs,\n nowMs,\n );\n if (!acquired) continue;\n // A per-run hook (recovery counting / dead-lettering) may settle the run terminally instead.\n const settled = onLocked ? await onLocked(run) : undefined;\n results.push(settled ?? (await this.resume(run.id)));\n }\n return results;\n }\n\n /**\n * Deliver an external signal to the run waiting on `token` and resume it with `payload`.\n * Returns the run result, or null if no run is waiting for that token.\n */\n /**\n * Publish a named event. It does two things, and returns how many runs it touched (the sum):\n * 1. **Resumes** every in-flight run waiting on it via `ctx.waitForEvent(name, { match })` whose\n * match the payload satisfies (fan-out, vs `signal`'s point-to-point token).\n * 2. **Starts** a fresh run of every workflow registered with `onEvent: [name]`, passing the\n * payload as input. Idempotent by `evt:<id>:<workflow>` — pass `opts.id` to dedupe redeliveries\n * of the same logical event (default: a fresh uuid, so each publish triggers once).\n */\n async publishEvent(name: string, payload: unknown, opts?: { id?: string }): Promise<number> {\n let touched = 0;\n const waiters = await this.store.listSignalWaiters(eventPrefix(name));\n for (const w of waiters) {\n if (eventMatches(payload, eventMatchOf(w.token))) {\n await this.signal(w.token, payload);\n touched += 1;\n }\n }\n const subscribers = this.eventTriggers.get(name);\n if (subscribers?.size) {\n const eventId = opts?.id ?? globalThis.crypto.randomUUID();\n for (const workflow of subscribers) {\n // A subscriber that rejects the payload (validateInput) must not block the others or the\n // waiters — its run simply never starts, mirroring fire-and-forget dead-letter routing.\n try {\n const batch = this.latest.get(workflow)?.eventBatch;\n if (batch) {\n // Coalesce: route the event into a per-workflow accumulator (one long-lived run that\n // debounces/batches and then starts the target with the collected payload(s)).\n await this.accumulators.route(workflow, batch, payload);\n } else {\n await this.start(workflow, payload, `evt:${eventId}:${workflow}`);\n }\n touched += 1;\n } catch {\n // skip this subscriber\n }\n }\n }\n return touched;\n }\n\n async signal(token: string, payload: unknown): Promise<RunResult | null> {\n const waiter = await this.store.takeSignalWaiter(token);\n if (!waiter) {\n // No one is waiting yet — buffer it so the next `waitForSignal(token)` consumes it instead of\n // dropping it (reliable signals; the basis of `signalWithStart`).\n await this.store.bufferSignal(token, payload);\n return null;\n }\n await this.store.saveCheckpoint(\n instantCheckpoint({\n runId: waiter.runId,\n seq: waiter.seq,\n name: `signal:${token}`,\n kind: 'signal',\n output: payload,\n }),\n );\n return this.resume(waiter.runId);\n }\n\n /**\n * Ensure a run exists for `runId`, then deliver a signal to it — atomically race-free thanks to\n * signal buffering: if the run is new (or busy / not yet waiting), the signal is buffered and\n * consumed when it reaches `waitForSignal(token)`. The canonical **durable-entity / accumulator**\n * pattern: one long-lived run per key (the `runId`) that loops on `waitForSignal`, fed events by\n * many `signalWithStart` calls. `start` is idempotent by `runId`, so concurrent callers converge on\n * one run. (Use a per-run `token`, e.g. derived from `runId`, so the signal targets this entity.)\n */\n async signalWithStart(\n workflow: WorkflowRef,\n input: unknown,\n runId: string,\n signal: { token: string; payload?: unknown },\n opts?: StartOptions,\n ): Promise<{ runId: string }> {\n // `start` is overloaded per ref kind (class | string); a `WorkflowRef` union fits neither\n // overload, so resolve to the string overload (the engine handles both at runtime).\n await this.start(workflow as string, input, runId, opts); // idempotent: no-op if run exists\n await this.signal(signal.token, signal.payload);\n return { runId };\n }\n\n /**\n * Report the result of a `ctx.task(name, …)` back to its run (async completion). The external\n * worker that the task dispatched to calls this when done; the run resumes with `result`. Returns\n * null if no run is waiting on the task (e.g. a duplicate/late delivery) — a safe no-op.\n */\n async completeTask(runId: string, name: string, result: unknown): Promise<RunResult | null> {\n return this.signal(`task:${runId}:${name}`, {\n ok: true,\n value: result,\n } satisfies Completion<unknown>);\n }\n\n /** Report that a `ctx.task` failed — the run resumes and throws a FatalError at the task. */\n async failTask(runId: string, name: string, error: string): Promise<RunResult | null> {\n return this.signal(`task:${runId}:${name}`, { ok: false, error } satisfies Completion<never>);\n }\n\n /**\n * Notify a parent that's waiting on `runId` as a child of its terminal outcome (the `ctx.child`\n * rendezvous). A no-op when no parent is waiting, so `execute()` can call it on every run without\n * knowing about the child feature.\n */\n private notifyParent(runId: string, completion: Completion<unknown>): void {\n void this.signal(`child:${runId}`, completion).catch(() => undefined);\n }\n\n /**\n * Cancel a run (e.g. from the dashboard). Returns null if the run does not exist. Pass\n * `{ compensate: true }` to undo the saga first: the suspended run is resumed so its completed\n * steps' compensations run in reverse (visible as `compensate:<step>` events), then it's marked\n * cancelled. Without it, cancellation is immediate (no undo).\n */\n async cancel(runId: string, opts?: { compensate?: boolean }): Promise<RunResult | null> {\n const run = await this.store.getRun(runId);\n if (!run) return null;\n // Already finished — nothing to cancel (and don't clobber a completed/dead run). This also stops\n // the child cascade below from looping on already-cancelled runs.\n if (run.status === 'completed' || run.status === 'cancelled' || run.status === 'dead') {\n return { runId, status: run.status, output: run.output, error: run.error };\n }\n // Compensating cancel: resume the run with a cancellation pending — replay re-registers the saga,\n // and at the suspension point execute() runs the undo and marks it cancelled. Run that resume in\n // the BACKGROUND so the caller (e.g. an HTTP request) never blocks on replaying the workflow +\n // compensations. `execute` holds the run's lease, so this can't double-run one a live worker owns\n // (its lease acquire fails and it no-ops); the broadcast tells that worker to abort cooperatively.\n if (opts?.compensate && (run.status === 'suspended' || run.status === 'running')) {\n this.cancelRequested.add(runId);\n if (this.controlPlane) {\n void this.controlPlane\n .publishControl({ kind: 'cancel', runId, from: this.instanceId })\n .catch(() => undefined);\n }\n queueMicrotask(() => {\n void this.resume(runId)\n .then(() => this.notifyCancelled(runId))\n .catch(() => undefined);\n });\n await this.cancelChildren(runId, opts);\n return { runId, status: run.status };\n }\n const error = { message: 'cancelled' };\n await this.store.updateRun(runId, { status: 'cancelled', error, updatedAt: new Date() });\n this.emit({ type: 'run.failed', runId, workflow: run.workflow, error });\n await this.cancelChildren(runId, opts);\n // Notify local cancel listeners now (a worker on this pod), and broadcast so the instance/worker\n // actually running this run learns of it and can abort cooperatively (the store already records\n // `cancelled`, but a busy worker won't re-read it).\n this.notifyCancelled(runId);\n if (this.controlPlane) {\n void this.controlPlane\n .publishControl({ kind: 'cancel', runId, from: this.instanceId })\n .catch(() => undefined);\n }\n // A cancelled singleton run frees its slot — wake the next gated waiter now (notify-on-release).\n void this.singletons.wakeNext(run).catch(() => undefined);\n return { runId, status: 'cancelled', error };\n }\n\n /**\n * Bulk-cancel every run matching a filter — e.g. cancel all `order` runs tagged `vip`, or every run\n * whose `tier` search attribute is `free`. The filter is a {@link RunQuery} (workflow / status / tag\n * / search-attribute predicates), so it reuses the same matching the dashboard list uses. Each match\n * is run through {@link cancel}, so the same plumbing applies per run: child cascade, the optional\n * saga `compensate`, local cancel listeners, and the control-plane broadcast that tells the owning\n * worker to abort. Returns one {@link RunResult} per matched run (already-finished matches report\n * their terminal status — `cancel` is a no-op on them, never clobbering a completed/dead run).\n */\n async cancelWhere(\n filter: Omit<RunQuery, 'limit' | 'offset'>,\n opts?: { compensate?: boolean },\n ): Promise<RunResult[]> {\n const runs = await this.store.listRuns(filter);\n const results: RunResult[] = [];\n for (const run of runs) {\n const r = await this.cancel(run.id, opts);\n if (r) results.push(r);\n }\n return results;\n }\n\n /**\n * Hard-delete a run and its entire subtree. Unlike {@link cancel} (which marks a run `cancelled`\n * but keeps it as history), delete REMOVES the run and all its rows (checkpoints, signal waiters,\n * search-attribute rows) — it vanishes from {@link getRun} and {@link listRuns}. Use it to purge a\n * finished run whose data is being deleted (e.g. a pipeline run whose result rows are cleared).\n *\n * Cascades depth-first via {@link getRunChildren} so children are gone before the parent (no\n * orphaned child runs). Prefer {@link cancel} first for a live run — deleting one mid-flight orphans\n * its worker (its next checkpoint write fails). Returns the number of runs deleted (0 if absent).\n */\n async deleteRun(runId: string): Promise<number> {\n const run = await this.store.getRun(runId);\n if (!run) return 0;\n // Collect children BEFORE deleting this run's checkpoints (getRunChildren reads them).\n let deleted = 0;\n for (const childId of await this.getRunChildren(runId)) {\n deleted += await this.deleteRun(childId);\n }\n await this.store.deleteRun(runId);\n return deleted + 1;\n }\n\n /**\n * Cascade cancellation to a run's children — both awaited (`ctx.child`, found via its live\n * `child:<id>` waiter) and fire-and-forget (`ctx.startChild`, found via its `spawn:<id>`\n * checkpoint). Recursive, so a whole subtree is cancelled; the terminal guard in `cancel` stops it\n * at finished / already-cancelled runs (no loops, no re-cancel).\n */\n private async cancelChildren(\n parentRunId: string,\n opts?: { compensate?: boolean },\n ): Promise<void> {\n for (const id of await this.getRunChildren(parentRunId)) {\n await this.cancel(id, opts).catch(() => undefined);\n }\n }\n\n /**\n * The ids of the runs a run spawned — both awaited (`ctx.child`) and fire-and-forget\n * (`ctx.startChild`, found via its `spawn:<id>` checkpoint). The canonical parent→children edge,\n * used for both cancellation cascades and the dashboard run-tree.\n *\n * An awaited child is discovered two ways, because the live `child:<id>` waiter only exists WHILE\n * the parent is suspended on it: the waiter resolves and is consumed the moment the child settles,\n * so a completed parent (or a completed awaited child) would otherwise drop out of the tree. The\n * `signal:child:<id>` checkpoint (the placeholder written when the parent first awaits the child,\n * overwritten as completed/failed when it settles) persists across completion, so we read both and\n * dedupe — the edge stays stable for a finished run, not just a live one.\n */\n async getRunChildren(parentRunId: string): Promise<string[]> {\n const childIds = new Set<string>();\n for (const w of await this.store.listSignalWaiters('child:')) {\n if (w.runId === parentRunId) childIds.add(w.token.slice('child:'.length));\n }\n // Targeted read: only the `signal:child:` / `spawn:` checkpoints, not the whole history. Falls\n // back to a full listCheckpoints + in-JS prefix scan for a custom store that omits the method.\n const prefixes = ['signal:child:', 'spawn:'];\n const childCheckpoints = this.store.listCheckpointsByNamePrefix\n ? await this.store.listCheckpointsByNamePrefix(parentRunId, prefixes)\n : (await this.store.listCheckpoints(parentRunId)).filter((cp) =>\n prefixes.some((p) => cp.name.startsWith(p)),\n );\n for (const cp of childCheckpoints) {\n if (cp.name.startsWith('signal:child:')) childIds.add(cp.name.slice('signal:child:'.length));\n if (cp.name.startsWith('spawn:') && typeof cp.output === 'string') childIds.add(cp.output);\n }\n return [...childIds];\n }\n\n /** The worker groups this engine dispatches to: every registered remote workflow's group, plus any\n * `extra` the caller declares. Local-step groups (a group consumed by in-process `@DurableStep`\n * workers, e.g. `pipeline`) aren't derivable from registrations — pass them via `extra` so a group\n * with backlog and ZERO workers is still reported (the alert case has no heartbeat to discover). */\n knownGroups(extra: string[] = []): string[] {\n const groups = new Set<string>(extra);\n for (const def of this.workflows.values()) {\n if (def.remote?.group) groups.add(def.remote.group);\n }\n return [...groups];\n }\n\n /** Per-group worker health (queue backlog + live worker heartbeats). Covers {@link knownGroups}\n * (so a registered group with backlog and ZERO workers still reports — the alert case) UNION the\n * groups discovered from live heartbeats (so a local-step group like `pipeline`, not derivable\n * from registrations, shows once its workers beat). Empty when no transport can introspect health\n * (only the BullMQ transport implements `groupHealth`). */\n async workerHealth(extra: string[] = []): Promise<GroupHealth[]> {\n const groups = new Set([...this.knownGroups(extra), ...(await this.pool.listWorkerGroups())]);\n const out: GroupHealth[] = [];\n for (const group of groups) {\n const health = await this.pool.groupHealth(group);\n if (health) out.push(health);\n }\n return out;\n }\n\n /**\n * Persist a streamed local-step lifecycle event from a remote workflow worker (see\n * {@link WorkflowStepEvent}). A Python `@workflow` runs its `ctx.step`s inline over one turn that\n * can last minutes; the worker streams each step's start/finish so the engine checkpoints it LIVE —\n * a step shows `running` the moment its body begins, then resolves to `completed`/`failed` with its\n * real wall-clock window and sub-process events — instead of every step appearing at once when the\n * turn ends. The turn's final `recordStep` command re-persists the same (runId, seq) checkpoint\n * idempotently, so this is purely additive observability and never changes the run's outcome.\n */\n private async persistStepEvent(event: WorkflowStepEvent): Promise<void> {\n const startedAt = new Date(event.startedAt);\n if (event.phase === 'running') {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: event.runId,\n seq: event.seq,\n name: event.name,\n kind: 'local',\n status: 'running',\n events: event.events,\n attempts: 1,\n enqueuedAt: startedAt,\n startedAt,\n finishedAt: startedAt, // placeholder until the step settles\n parallelGroup: event.parallelGroup,\n }),\n );\n this.emit({\n type: 'step.started',\n runId: event.runId,\n seq: event.seq,\n name: event.name,\n kind: 'local',\n });\n return;\n }\n const failed = event.phase === 'failed';\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: event.runId,\n seq: event.seq,\n name: event.name,\n kind: 'local',\n status: failed ? 'failed' : 'completed',\n output: failed ? undefined : event.output,\n error: failed ? event.error : undefined,\n events: event.events,\n attempts: 1,\n enqueuedAt: startedAt,\n startedAt,\n finishedAt: event.finishedAt != null ? new Date(event.finishedAt) : new Date(),\n parallelGroup: event.parallelGroup,\n }),\n );\n this.emit({\n type: failed ? 'step.failed' : 'step.completed',\n runId: event.runId,\n seq: event.seq,\n name: event.name,\n kind: 'local',\n output: failed ? undefined : event.output,\n error: failed ? event.error : undefined,\n });\n }\n\n /**\n * Announce a local step's body has begun and (when `trackStepStart`) checkpoint it as `running`,\n * so it's visible in flight rather than appearing only on completion. The checkpoint is a\n * placeholder overwritten by {@link completeStep}/{@link failStep}; it never short-circuits replay\n * (only `completed` does), so a crash mid-body just re-runs the step. The `step.started` event\n * fires regardless — the live SSE view sees the start even with persistence off.\n */\n private async startStep(step: StepRecord): Promise<void> {\n if (this.trackStepStart) {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n status: 'running',\n input: step.input,\n events: step.events,\n attempts: step.attempts,\n workerGroup: step.workerGroup,\n enqueuedAt: step.enqueuedAt,\n startedAt: step.startedAt,\n finishedAt: step.startedAt, // placeholder until the body settles\n }),\n );\n }\n this.emit({\n type: 'step.started',\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n });\n }\n\n /** Checkpoint a finished step and announce it — the two things that must always happen together. */\n private async completeStep(step: StepRecord & { output: unknown }): Promise<void> {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n status: 'completed',\n input: step.input,\n output: step.output,\n events: step.events,\n attempts: step.attempts,\n workerGroup: step.workerGroup,\n enqueuedAt: step.enqueuedAt,\n startedAt: step.startedAt,\n finishedAt: new Date(),\n }),\n );\n this.emit({\n type: 'step.completed',\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n output: step.output,\n queueMs: step.startedAt.getTime() - step.enqueuedAt.getTime(),\n durationMs: Date.now() - step.startedAt.getTime(),\n });\n }\n\n /** Checkpoint a step that failed terminally, so the failure point is visible (not just the run). */\n private async failStep(step: StepRecord & { error: StepError }): Promise<void> {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n status: 'failed',\n input: step.input,\n error: step.error,\n events: step.events,\n attempts: step.attempts,\n workerGroup: step.workerGroup,\n enqueuedAt: step.enqueuedAt,\n startedAt: step.startedAt,\n finishedAt: new Date(),\n }),\n );\n this.emit({\n type: 'step.failed',\n runId: step.runId,\n seq: step.seq,\n name: step.name,\n kind: step.kind,\n error: step.error,\n queueMs: step.startedAt.getTime() - step.enqueuedAt.getTime(),\n durationMs: Date.now() - step.startedAt.getTime(),\n });\n }\n\n private async execute(run: WorkflowRun, fn: WorkflowFn): Promise<RunResult> {\n const registered = this.workflows.get(versionKey(run.workflow, run.workflowVersion));\n // Hold the lease for the WHOLE execution — whatever path got us here (leased sweep, a signal, a\n // remote result, a dashboard action). The leased sweeps already own it; the event-driven paths\n // don't, so acquire it here. If another instance owns it, don't double-run. While we run, renew\n // the lease periodically so a long run keeps it (a crashed worker's lease still expires and is\n // reclaimed by periodic recovery).\n const lockNow = this.clock();\n if (run.lockedBy !== this.instanceId || (run.lockedUntil ?? 0) <= lockNow) {\n if (\n !(await this.store.tryLockRun(run.id, this.instanceId, lockNow + this.leaseMs, lockNow))\n ) {\n return { runId: run.id, status: run.status };\n }\n }\n const renew = setInterval(\n () => {\n void this.store\n .renewRunLock(run.id, this.instanceId, this.clock() + this.leaseMs)\n .catch(() => undefined);\n },\n Math.max(50, Math.floor(this.leaseMs / 2)),\n );\n renew.unref?.();\n try {\n // A remote (e.g. Python) workflow is advanced by dispatching workflow tasks, not by running an\n // in-process body — but everything around it (lease, recovery, timers, the resume that lands us\n // here on a step result) is identical, so it branches here under the same lease.\n const result = registered?.remote\n ? await this.runRemoteExecution(run, registered)\n : await this.runExecution(run, fn, registered);\n // Notify-on-release: a singleton run that just reached a terminal state freed a slot — wake the\n // next gated waiter(s) now instead of waiting for the ~1s retry timer. Fire-and-forget so it\n // never blocks the settling run; the durable timer is still the cross-instance/crash fallback.\n if (\n registered?.singleton &&\n (result.status === 'completed' ||\n result.status === 'failed' ||\n result.status === 'cancelled' ||\n result.status === 'dead')\n ) {\n void this.singletons.wakeNext(run).catch(() => undefined);\n }\n return result;\n } finally {\n clearInterval(renew);\n }\n }\n\n /**\n * Advance a remote (cross-SDK) workflow one turn: hand its history to the executor (which dispatches\n * a workflow task to the worker and awaits its replay) and apply the decision. Mirrors\n * {@link runExecution}'s settle/suspend; the lease is held by {@link execute}. The result that lands\n * us back here (a remote step finished, a timer fired) goes through `resume` like any TS workflow.\n */\n /**\n * Apply a terminal/suspended transition once: persist the new run status, emit the matching\n * lifecycle event, and (on completion/failure) wake a waiting parent. Both the TS and remote\n * executors funnel their completed/failed/suspended outcomes through here so a status update can\n * never drift from its event or `notifyParent` call. Does NOT touch the run lock — each executor\n * keeps its own lease handling (the TS executor's `finally`, the remote path's caller).\n */\n private async settleRun(run: WorkflowRun, outcome: RunOutcome): Promise<RunResult> {\n const updatedAt = new Date();\n if (outcome.kind === 'completed') {\n // Clear any error from an earlier failed-then-retried attempt — a completed run is a success.\n await this.store.updateRun(run.id, {\n status: 'completed',\n output: outcome.output,\n error: undefined,\n updatedAt,\n });\n this.emit({\n type: 'run.completed',\n runId: run.id,\n workflow: run.workflow,\n output: outcome.output,\n });\n void this.notifyParent(run.id, { ok: true, value: outcome.output });\n return { runId: run.id, status: 'completed', output: outcome.output };\n }\n if (outcome.kind === 'failed') {\n await this.store.updateRun(run.id, { status: 'failed', error: outcome.error, updatedAt });\n this.emit({\n type: 'run.failed',\n runId: run.id,\n workflow: run.workflow,\n error: outcome.error,\n });\n void this.notifyParent(run.id, { ok: false, error: outcome.error.message });\n return { runId: run.id, status: 'failed', error: outcome.error };\n }\n await this.store.updateRun(run.id, { status: 'suspended', wakeAt: outcome.wakeAt, updatedAt });\n this.emit({ type: 'run.suspended', runId: run.id, workflow: run.workflow });\n return { runId: run.id, status: 'suspended' };\n }\n\n private async runRemoteExecution(\n run: WorkflowRun,\n registered: RegisteredWorkflow,\n ): Promise<RunResult> {\n const remote = registered.remote as NonNullable<RegisteredWorkflow['remote']>;\n if (run.status === 'pending') {\n await this.store.updateRun(run.id, { status: 'running', updatedAt: new Date() });\n run.status = 'running';\n this.emit({ type: 'run.started', runId: run.id, workflow: run.workflow });\n }\n if (registered.singleton && !(await this.singletons.admit(run, registered.singleton))) {\n const wakeAt = this.singletons.retryWakeAt();\n await this.store.updateRun(run.id, { status: 'suspended', wakeAt, updatedAt: new Date() });\n this.emit({ type: 'run.suspended', runId: run.id, workflow: run.workflow });\n await this.store.releaseRunLock(run.id);\n return { runId: run.id, status: 'suspended' };\n }\n\n const history = await this.remoteHistory(run.id);\n let decision: WorkflowDecision;\n try {\n decision = await remote.executor.advance(run, history);\n } catch (err) {\n // A RemoteWorkflowTimeout is NOT a failure: the advance only timed out (the decision was likely\n // dropped, while the work may have actually completed). Failing the run here would be wrong — and\n // would notify the parent of a false failure. Instead RELEASE the lease and leave the run in its\n // current `running` state so `recoverIncomplete` re-acquires the now-free lease and re-drives it;\n // the re-driven turn replays completed steps from history and, if the work was done, returns the same\n // `completed` decision → settles → notifies the parent. Opt-in: only reachable when the executor\n // was constructed with a `timeoutMs` (absent = prior unbounded await, unchanged).\n //\n // KNOWN HAZARD (follow-up): if the timeout fires while a worker is LEGITIMATELY still executing a\n // not-yet-checkpointed step, the re-drive re-runs that step → DUPLICATE side effects. So this\n // timeout is only safe when set GENEROUSLY (> the longest legitimate single turn). The robust fix\n // — a liveness/heartbeat-rearmed deadline so only a genuinely-dead worker re-drives — is the\n // documented next step (Track A diagnosis doc, \"Part B\"); NOT implemented here.\n //\n // Lease lifecycle: `execute` clears its renew interval in its `finally` once this returns, so the\n // lease (released just below) stays free. `releaseRunLock` is idempotent, and `renewRunLock` is a\n // no-op once `lockedBy` is cleared, so a renew tick racing the release cannot re-acquire it.\n if (err instanceof RemoteWorkflowTimeout) {\n await this.store.releaseRunLock(run.id);\n // The suspended path returned early above; run is always `running` here — left for recovery to re-drive.\n return { runId: run.id, status: 'running' as const };\n }\n const error = {\n message: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n };\n // terminal failure: lease expires naturally — no recovery re-drive will race it\n await this.store.updateRun(run.id, { status: 'failed', error, updatedAt: new Date() });\n this.emit({ type: 'run.failed', runId: run.id, workflow: run.workflow, error });\n return { runId: run.id, status: 'failed', error };\n }\n\n if (decision.status === 'completed') {\n // Persist the local steps THIS turn ran before marking the run done. A workflow that runs\n // straight to completion in a single turn (every step inline, never suspending — e.g. a Python\n // @workflow whose body is a sequence of ctx.step calls) emits ALL its recordStep commands on\n // this terminal turn; without applying them the run shows `completed` with zero recorded steps.\n // Only this turn's NEW steps are present (prior turns' steps replay as `found`, emitting no\n // command), so there's no duplication.\n await this.applyCommands(run, decision.commands);\n return this.settleRun(run, { kind: 'completed', output: decision.output });\n }\n if (decision.status === 'failed') {\n // Same as completed: persist the steps this turn ran — including the failed one (the worker\n // records a failed-step command before raising) — so the dashboard shows WHERE it failed.\n await this.applyCommands(run, decision.commands);\n return this.settleRun(run, {\n kind: 'failed',\n error: decision.error ?? { message: 'workflow failed' },\n });\n }\n\n if (decision.status === 'cancelled') {\n // The worker bailed at an op boundary because the run was cancelled mid-turn — `cancel` already\n // set status=cancelled, cascaded to children and emitted the lifecycle event. Persist the steps\n // that DID run this turn (partial progress / where it stopped) and reassert `cancelled`\n // (idempotent with `cancel`'s write; preserves the existing error). The point is to NOT resurrect\n // the run to `suspended` or flip it to `failed` — both of which a normal turn result would do.\n await this.applyCommands(run, decision.commands);\n await this.store.updateRun(run.id, { status: 'cancelled', updatedAt: new Date() });\n return { runId: run.id, status: 'cancelled' };\n }\n\n // continue: persist any local steps the replay ran, dispatch the blocking ops, then suspend. When\n // those resolve (a result lands, a timer fires) `resume` brings us back for the next turn.\n const wakeAt = await this.applyCommands(run, decision.commands);\n return this.settleRun(run, { kind: 'suspended', wakeAt });\n }\n\n /** The run's resolved durable ops as replay inputs: completed/failed steps + elapsed timers. */\n private async remoteHistory(runId: string): Promise<HistoryEvent[]> {\n const checkpoints = await this.store.listCheckpoints(runId);\n const kindOf: Record<StepKind, HistoryEvent['kind']> = {\n remote: 'call',\n local: 'step',\n sleep: 'timer',\n signal: 'signal',\n };\n const events: HistoryEvent[] = [];\n for (const cp of checkpoints) {\n if (cp.status === 'completed' || cp.status === 'failed') {\n // A child run resolves THROUGH the signal machinery (a `child:<id>` waiter notified on the\n // child's terminal state), so its checkpoint is kind `signal` with a `signal:child:` name and\n // a Completion payload. Surface it as a `child` event with the value/error unwrapped.\n if (cp.kind === 'signal' && cp.name.startsWith('signal:child:')) {\n const completion = cp.output as Completion<unknown> | undefined;\n events.push({\n seq: cp.seq,\n kind: 'child',\n output: completion?.ok ? completion.value : undefined,\n error:\n completion && completion.ok === false ? { message: completion.error } : undefined,\n });\n continue;\n }\n events.push({\n seq: cp.seq,\n kind: kindOf[cp.kind] ?? 'step',\n // A signal checkpoint's name is the internal `signal:<token>`, not the workflow-level signal\n // name the replay used — omit it so the replay matches on seq + kind (its determinism anchor).\n name: cp.kind === 'signal' ? undefined : cp.name,\n output: cp.status === 'completed' ? cp.output : undefined,\n error: cp.status === 'failed' ? cp.error : undefined,\n });\n } else if (cp.kind === 'sleep' && cp.wakeAt != null && cp.wakeAt <= this.clock()) {\n // a still-`pending` sleep whose deadline has passed reads as a resolved timer on replay.\n events.push({ seq: cp.seq, kind: 'timer', name: cp.name });\n }\n }\n return events.sort((a, b) => a.seq - b.seq);\n }\n\n /** Apply a turn's commands: persist recorded local steps, dispatch remote calls, schedule timers.\n * Returns the earliest timer deadline to suspend on (or undefined — suspended on a result). */\n private async applyCommands(\n run: WorkflowRun,\n commands: WorkflowCommand[],\n ): Promise<number | undefined> {\n let wakeAt: number | undefined;\n for (const cmd of commands) {\n const at = new Date();\n const id = stepId(run.id, cmd.seq);\n if (cmd.kind === 'recordStep') {\n // Prefer the step's real wall-clock window + sub-process events (carried by the command, and\n // already streamed live via persistStepEvent) so the checkpoint shows a true duration and its\n // p-process trail — not a 0ms placeholder. Fall back to apply-time for older workers.\n const startedAt = cmd.startedAt != null ? new Date(cmd.startedAt) : at;\n const finishedAt = cmd.finishedAt != null ? new Date(cmd.finishedAt) : at;\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n kind: 'local',\n status: cmd.error ? 'failed' : 'completed',\n output: cmd.output,\n error: cmd.error,\n events: cmd.events,\n attempts: 1,\n enqueuedAt: startedAt,\n startedAt,\n finishedAt,\n // Carry the worker's `parallelGroup` (a Python `ctx.gather` tags every step in the fan with\n // the same group) onto the checkpoint, so the dashboard can render the steps as one parallel\n // group instead of a sequential list. Additive: undefined for ordinary sequential steps.\n parallelGroup: cmd.parallelGroup,\n }),\n );\n this.emit({\n type: cmd.error ? 'step.failed' : 'step.completed',\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n kind: 'local',\n output: cmd.output,\n error: cmd.error,\n });\n } else if (cmd.kind === 'call') {\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n kind: 'remote',\n status: 'pending',\n input: cmd.input,\n attempts: 1,\n workerGroup: cmd.group,\n enqueuedAt: at,\n startedAt: at,\n finishedAt: at,\n }),\n );\n await this.pool.dispatch(\n {\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n stepId: id,\n group: cmd.group,\n input: cmd.input,\n traceparent: this.traceparent?.(),\n context: this.context?.(),\n attempt: 1,\n },\n undefined,\n );\n this.emit({\n type: 'step.started',\n runId: run.id,\n seq: cmd.seq,\n name: cmd.name,\n kind: 'remote',\n });\n } else if (cmd.kind === 'sleep') {\n const deadline = this.clock() + cmd.ms;\n await this.store.saveCheckpoint(\n stepCheckpoint({\n runId: run.id,\n seq: cmd.seq,\n name: `sleep:${cmd.seq}`,\n kind: 'sleep',\n status: 'pending',\n attempts: 1,\n wakeAt: deadline,\n enqueuedAt: at,\n startedAt: at,\n finishedAt: at,\n }),\n );\n wakeAt = wakeAt == null ? deadline : Math.min(wakeAt, deadline);\n } else if (cmd.kind === 'waitSignal') {\n // Park on a signal: register a waiter at this seq so engine.signal(token) lands the resolving\n // `signal` checkpoint here and resumes the run. The token is the signal name, so an external\n // engine.signal(name, payload) delivers it. If the signal was already delivered (buffered\n // before the workflow reached this point — e.g. signalWithStart), resolve it now and re-drive\n // on a macrotask, AFTER this turn suspends and frees the run lock (a re-entrant resume bails).\n const buffered = await this.store.takeBufferedSignal(cmd.signal);\n if (buffered) {\n await this.store.saveCheckpoint(\n instantCheckpoint({\n runId: run.id,\n seq: cmd.seq,\n name: `signal:${cmd.signal}`,\n kind: 'signal',\n output: buffered.payload,\n }),\n );\n setTimeout(() => void this.resume(run.id).catch(() => undefined), 0);\n } else {\n await this.store.putSignalWaiter({ token: cmd.signal, runId: run.id, seq: cmd.seq });\n }\n } else if (cmd.kind === 'startChild') {\n // Start a child run and await it (the worker's ctx.start_child suspends until the child's\n // result is in history). Mirror the in-process `ctx.child`: register a `child:<id>` waiter at\n // this seq — the child notifies it on its terminal state (engine.notifyParent) — then start the\n // child once, deferred so a fast child can't reentrantly resume this still-suspending parent,\n // and id-idempotent so replay/recovery never double-starts it.\n const childId = `${run.id}.child.${cmd.seq}`;\n await this.store.putSignalWaiter({\n token: `child:${childId}`,\n runId: run.id,\n seq: cmd.seq,\n });\n if (!(await this.store.getRun(childId))) {\n queueMicrotask(\n () => void this.start(cmd.workflow, cmd.input, childId).catch(() => undefined),\n );\n }\n } else {\n throw new Error(\n `remote workflow command '${(cmd as { kind: string }).kind}' is not supported yet`,\n );\n }\n }\n return wakeAt;\n }\n\n /** The run body, lease held + renewed by {@link execute}. */\n private async runExecution(\n run: WorkflowRun,\n fn: WorkflowFn,\n registered: RegisteredWorkflow | undefined,\n ): Promise<RunResult> {\n // First execution of an enqueued run: mark it running and announce the start, BEFORE the singleton\n // gate — `singletons.admit` only counts `running`/`suspended` runs, so a still-`pending` run could\n // never be admitted. A resumed run is already past `pending`, so this fires exactly once.\n if (run.status === 'pending') {\n await this.store.updateRun(run.id, { status: 'running', updatedAt: new Date() });\n run.status = 'running';\n this.emit({ type: 'run.started', runId: run.id, workflow: run.workflow });\n }\n // Singleton admission gate: if this run shares its key with `limit` older in-flight runs, wait\n // (suspend on a short timer) until a slot frees instead of running now. Re-checked on each resume.\n if (registered?.singleton && !(await this.singletons.admit(run, registered.singleton))) {\n const wakeAt = this.singletons.retryWakeAt();\n await this.store.updateRun(run.id, { status: 'suspended', wakeAt, updatedAt: new Date() });\n this.emit({ type: 'run.suspended', runId: run.id, workflow: run.workflow });\n await this.store.releaseRunLock(run.id);\n return { runId: run.id, status: 'suspended' };\n }\n // Saga compensations registered by completed steps; run in reverse if the run later fails.\n const compensations: Compensation[] = [];\n // Load this run's checkpoints ONCE and key them by seq, so replaying the completed prefix reads\n // from memory instead of one `getCheckpoint` SELECT per primitive (the O(N²) replay-reads fix).\n // Read once at execution start: a checkpoint written AFTER this snapshot (the signal/timer/child\n // this resume wakes on, or one written later in this same execution) is absent from the map, and\n // the ctx falls back to the live store for any absent seq — so replay semantics are unchanged.\n const snapshot = await this.store.listCheckpoints(run.id);\n const replay = new Map<number, StepCheckpoint>();\n for (const cp of snapshot) replay.set(cp.seq, cp);\n const ctx = createWorkflowCtx(this.ctxHostFor(replay), run.id, compensations, run.workflow);\n try {\n const output = await fn(ctx, run.input);\n return this.settleRun(run, { kind: 'completed', output });\n } catch (err) {\n if (err instanceof ContinueAsNew) {\n // Hand off to a fresh execution with a clean history: complete this run, then start the next\n // (`<id>~N`) with the new input. Deferred + idempotent by the continuation id, so a crash\n // mid-handoff re-derives the same next run instead of forking.\n await this.store.updateRun(run.id, {\n status: 'completed',\n output: undefined,\n error: undefined,\n updatedAt: new Date(),\n });\n this.emit({ type: 'run.completed', runId: run.id, workflow: run.workflow });\n void this.notifyParent(run.id, { ok: true, value: undefined });\n const nextId = nextContinuationId(run.id);\n queueMicrotask(\n () => void this.start(run.workflow, err.input, nextId).catch(() => undefined),\n );\n return { runId: run.id, status: 'completed' };\n }\n if (err instanceof WorkflowSuspended) {\n // A compensating cancel resumed this run to reach here: the replay re-registered the saga,\n // so undo the completed steps in reverse and mark it cancelled instead of re-suspending.\n if (this.cancelRequested.has(run.id)) {\n this.cancelRequested.delete(run.id);\n for (let i = compensations.length - 1; i >= 0; i -= 1) {\n const comp = compensations[i];\n if (comp) await this.runCompensation(run, comp);\n }\n const error = { message: 'cancelled' };\n await this.store.updateRun(run.id, { status: 'cancelled', error, updatedAt: new Date() });\n this.emit({ type: 'run.failed', runId: run.id, workflow: run.workflow, error });\n return { runId: run.id, status: 'cancelled', error };\n }\n return this.settleRun(run, { kind: 'suspended', wakeAt: err.wakeAt });\n }\n const error = {\n message: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n };\n // Saga: undo completed steps in reverse, each retried up to `compensationRetries`. Outcomes\n // are emitted as `compensate:<step>` step events so a stranded undo is VISIBLE (not silently\n // swallowed) in the dashboard/telescope; a failing one is still skipped so it can't mask the\n // original failure or strand the rest. (Compensations should be idempotent.)\n for (let i = compensations.length - 1; i >= 0; i -= 1) {\n const comp = compensations[i];\n if (!comp) continue;\n await this.runCompensation(run, comp);\n }\n return this.settleRun(run, { kind: 'failed', error });\n } finally {\n // Release the recovery lease once the run reaches a terminal/suspended state, so the\n // next instance (or the timer poller) can pick it up promptly.\n await this.store.releaseRunLock(run.id);\n }\n }\n\n /**\n * Run one saga compensation, retried up to `compensationRetries`, emitting a `compensate:<step>`\n * step event for its outcome so a stranded undo is visible. Never throws — a permanently-failing\n * compensation is skipped so it can't mask the original failure.\n */\n private async runCompensation(run: WorkflowRun, comp: Compensation): Promise<void> {\n const name = `compensate:${comp.name}`;\n for (let attempt = 1; attempt <= this.compensationRetries; attempt += 1) {\n const startedAt = Date.now();\n try {\n await comp.fn();\n this.emit({\n type: 'step.completed',\n runId: run.id,\n workflow: run.workflow,\n name,\n kind: 'local',\n durationMs: Date.now() - startedAt,\n });\n return;\n } catch (err) {\n if (attempt >= this.compensationRetries) {\n this.emit({\n type: 'step.failed',\n runId: run.id,\n workflow: run.workflow,\n name,\n kind: 'local',\n error: { message: err instanceof Error ? err.message : String(err) },\n durationMs: Date.now() - startedAt,\n });\n }\n }\n }\n }\n\n /** The seam handed to {@link createWorkflowCtx}: the authoring API reaches durability + lifecycle\n * (checkpointing, dispatch, child start) through this, so the ctx primitives live in their own\n * module and the engine stays the orchestrator. */\n private ctxHostFor(replay?: Map<number, StepCheckpoint>): CtxHost {\n return {\n store: this.store,\n replay,\n clock: this.clock,\n webhookUrl: this.webhookUrl,\n startStep: (s) => this.startStep(s),\n completeStep: (s) => this.completeStep(s),\n failStep: (s) => this.failStep(s),\n callRemote: (runId, seq, step, input, queue, transport, admission) =>\n this.callRemote(runId, seq, step, input, queue, transport, replay, admission),\n // Defer so a fast child can't reentrantly resume a still-running parent.\n startChild: (workflow, input, id, priority) => {\n queueMicrotask(\n () => void this.start(workflow, input, id, { priority }).catch(() => undefined),\n );\n },\n signalEntity: (name, key, op, arg, reply) => {\n queueMicrotask(\n () => void this.entities.dispatch(name, key, op, arg, reply).catch(() => undefined),\n );\n },\n interceptStep: (invocation, body) => this.interceptStep(invocation, body),\n };\n }\n\n /**\n * Resume a run paused at a {@link WorkflowCtx.breakpoint} (e.g. the dashboard \"continue\" button).\n * Finds the run's pending breakpoint checkpoint and signals it. Returns null if the run isn't\n * paused at a breakpoint.\n */\n async continue(runId: string): Promise<RunResult | null> {\n const checkpoints = await this.store.listCheckpoints(runId);\n const bp = checkpoints.find(isBreakpoint);\n if (!bp) return null;\n return this.signal(breakpointToken(runId, bp.seq), undefined);\n }\n\n /**\n * Read the latest value a run published for `key` via {@link WorkflowCtx.setEvent} — a\n * side-effect-free query of a live (or finished) run's state. Returns `undefined` if the run\n * never published that key. The suspend-model counterpart of a Temporal query.\n */\n async getEvent<TValue = unknown>(runId: string, key: string): Promise<TValue | undefined> {\n const name = `event:${key}`;\n // Targeted read: the highest-seq checkpoint for this name is the most recent value (a re-published\n // key overwrites at a higher seq), matching the old \"last in seq order wins\" scan. Falls back to a\n // full listCheckpoints scan (last match in seq-ascending order wins) for a store that omits it.\n if (this.store.getLatestCheckpointByName) {\n const latest = await this.store.getLatestCheckpointByName(runId, name);\n return latest?.output as TValue | undefined;\n }\n // listCheckpoints is ordered by seq ascending, so the last match is the most recent value.\n let latest: TValue | undefined;\n for (const cp of await this.store.listCheckpoints(runId))\n if (cp.name === name) latest = cp.output as TValue;\n return latest;\n }\n\n /**\n * Register a validator gating `engine.update(runId, name, …)` for runs of `workflow`. The\n * validator runs BEFORE the update is delivered, so a rejection leaves the run untouched. One\n * validator per (workflow, update name); registering again replaces it.\n */\n registerUpdateValidator<TArg>(\n workflow: string,\n name: string,\n validate: UpdateValidator<TArg>,\n ): void {\n this.updateValidators.set(`${workflow}:${name}`, validate as UpdateValidator);\n }\n\n /**\n * Deliver a validated update to the run waiting at `ctx.onUpdate(name)`. Runs the registered\n * validator (if any) first: on rejection returns `{ accepted: false, reason }` without disturbing\n * the run; otherwise delivers `arg` and resumes, returning `{ accepted: true, run }` (`run` is null\n * if nothing was waiting — a too-early or duplicate update).\n */\n async update(runId: string, name: string, arg: unknown): Promise<UpdateResult> {\n const run = await this.store.getRun(runId);\n if (!run) return { accepted: false, reason: `run ${runId} not found` };\n const validate = this.updateValidators.get(`${run.workflow}:${name}`);\n if (validate) {\n try {\n const reason = await validate(arg);\n if (typeof reason === 'string' && reason.length > 0) return { accepted: false, reason };\n } catch (err) {\n return { accepted: false, reason: err instanceof Error ? err.message : String(err) };\n }\n }\n const result = await this.signal(`update:${runId}:${name}`, arg);\n return { accepted: true, run: result };\n }\n\n private async callRemote<TInput, TOutput>(\n runId: string,\n seq: number,\n step: RemoteStepDef<TInput, TOutput>,\n input: TInput,\n queue?: string,\n transport?: string,\n replay?: Map<number, StepCheckpoint>,\n admission?: { priority?: number | undefined; fairnessKey?: string | undefined },\n ): Promise<TOutput> {\n // Read the prefix from the per-execution snapshot (avoids the O(N²) replay SELECTs); a seq absent\n // from the snapshot — not yet dispatched, or written after the snapshot — falls back to the store.\n const existing = replay?.get(seq) ?? (await this.store.getCheckpoint(runId, seq));\n if (existing && existing.name !== step.name) {\n throw new NonDeterminismError(runId, seq, step.name, existing.name);\n }\n if (existing?.status === 'completed') return existing.output as TOutput;\n if (this.pool.size === 0) throw new Error('remote steps require a Transport');\n // A step with a liveness `timeoutMs` keeps the in-memory await + heartbeat path (re-dispatch a\n // presumed-dead worker). Without one, the call SUSPENDS DURABLY: dispatch, persist a `pending`\n // checkpoint, and let the result resume the run on whichever instance receives it — so a worker\n // pod can scale down or crash mid-step without losing the run or re-running completed work.\n if (step.timeoutMs) return this.callRemoteInMemory(runId, seq, step, input, transport);\n if (existing?.status === 'pending') throw new WorkflowSuspended(); // dispatched; keep waiting\n\n // Durable retry: a failed attempt re-dispatches up to `retries`, spacing attempts by `backoff` —\n // unless the worker marked the error non-retryable (a deterministic verdict like a declined card).\n // The retry deadline is stamped on the failed checkpoint as `wakeAt` (clock-space, persisted) the\n // first time we see it, so it's stable across replays and survives a crash.\n let attempt = 1;\n if (existing?.status === 'failed') {\n const maxAttempts = Math.max(1, step.retries ?? 1);\n const retryable = existing.error?.retryable !== false;\n if (!retryable || existing.attempts >= maxAttempts) throw new RemoteStepError(existing.error);\n if (existing.wakeAt == null) {\n const wakeAt = this.clock() + backoffDelay(existing.attempts, step);\n await this.store.saveCheckpoint({ ...existing, wakeAt });\n throw new WorkflowSuspended(wakeAt);\n }\n if (this.clock() < existing.wakeAt) throw new WorkflowSuspended(existing.wakeAt);\n attempt = existing.attempts + 1;\n }\n\n const id = stepId(runId, seq);\n // Flow control: a queued call that can't be admitted (concurrency/rate) does NOT dispatch — the\n // run re-suspends with the queue's retry time and the timer poller re-tries admission later, so\n // the limit is durable. The admitted slot is released when the result lands (completeRemoteResult).\n if (queue && this.admission.handles(queue)) {\n // Admission carries the per-call priority + fairness key (default the runId so each run is its\n // own fairness bucket), and the stepId as a STABLE waiter id so the backend tracks one waiter\n // across this call's durable retries. Ordering lives in the backend (in-process by default, or\n // global) — this is the dispatch/admission layer, not the positional replay path.\n const decision = await this.admission.tryAdmit(queue, {\n priority: admission?.priority,\n key: admission?.fairnessKey ?? runId,\n waiterId: id,\n });\n if (!decision.ok) {\n // Remember this run as blocked on `queue` so a freed-slot signal can wake it early.\n const waiters = this.queueWaiters.get(queue) ?? new Set<string>();\n waiters.add(runId);\n this.queueWaiters.set(queue, waiters);\n throw new WorkflowSuspended(decision.retryAt);\n }\n this.queueWaiters.get(queue)?.delete(runId);\n this.stepQueue.set(id, queue);\n }\n\n const validInput = step.input.parse(input);\n const enqueuedAt = new Date();\n // Persist the pending checkpoint BEFORE dispatching, so a fast result always finds it to complete.\n await this.store.saveCheckpoint({\n runId,\n seq,\n name: step.name,\n kind: 'remote',\n stepId: id,\n status: 'pending',\n input: validInput,\n attempts: attempt,\n workerGroup: step.group,\n enqueuedAt,\n startedAt: enqueuedAt, // placeholders until the worker result lands\n finishedAt: enqueuedAt,\n });\n await this.pool.dispatch(\n {\n runId,\n seq,\n name: step.name,\n stepId: id,\n group: step.group,\n input: validInput,\n traceparent: this.traceparent?.(),\n context: this.context?.(),\n priority: admission?.priority,\n attempt,\n },\n transport,\n );\n this.emit({ type: 'step.started', runId, seq, name: step.name, kind: 'remote' });\n throw new WorkflowSuspended();\n }\n\n /**\n * Complete a durable remote step from its worker result and resume the run — runs on whichever\n * instance receives the result (the dispatching one may be gone), so the run is crash/scale-safe.\n * A no-op if the checkpoint isn't `pending` (a duplicate or late delivery).\n */\n private async completeRemoteResult(result: StepResult): Promise<void> {\n const cp = await this.store.getCheckpoint(result.runId, result.seq);\n if (!cp || cp.status !== 'pending') return;\n // A result settling this step frees its flow-control slot (no-op if it wasn't queued). Done\n // before the cancelled-run early-return below, so a cancellation can't leak the slot. Released\n // fire-and-forget: the slot/notify is best-effort (a global backend self-heals via lease), and\n // not awaiting keeps it off the result-processing critical path (no ordering shift).\n void this.releaseQueueSlot(cp.stepId).catch(() => undefined);\n // Drop a late result for a run that was cancelled/finished meanwhile — don't complete the step\n // or resume (the run is already terminal). This is the engine side of cooperative cancellation.\n const run = await this.store.getRun(result.runId);\n if (run && (run.status === 'cancelled' || run.status === 'completed')) return;\n const finishedAt = new Date();\n const startedAt = result.startedAt ? new Date(result.startedAt) : cp.startedAt;\n await this.store.saveCheckpoint({\n ...cp,\n status: result.status,\n output: result.status === 'completed' ? result.output : cp.output,\n error: result.error,\n events: result.events ?? cp.events,\n startedAt,\n finishedAt,\n });\n this.emit({\n type: result.status === 'completed' ? 'step.completed' : 'step.failed',\n runId: result.runId,\n seq: result.seq,\n name: cp.name,\n kind: cp.kind,\n output: result.output,\n error: result.error,\n queueMs: startedAt.getTime() - cp.enqueuedAt.getTime(),\n durationMs: finishedAt.getTime() - startedAt.getTime(),\n });\n await this.resume(result.runId);\n }\n\n /**\n * A slot freed on `queue` (a fleet-wide signal): resume this instance's runs blocked on it so they\n * re-contend now instead of at their retry tick. Snapshot-and-clear — a run still blocked after the\n * retry re-registers itself, and one that's gone (cancelled/admitted) is dropped. Best-effort.\n */\n private wakeQueueWaiters(queue: string): void {\n const waiters = this.queueWaiters.get(queue);\n if (!waiters || waiters.size === 0) return;\n const runIds = [...waiters];\n waiters.clear();\n for (const runId of runIds) void this.resume(runId).catch(() => undefined);\n }\n\n /** Release the flow-control slot a dispatched step held (if any), by its stepId. */\n private async releaseQueueSlot(id: string): Promise<void> {\n const queue = this.stepQueue.get(id);\n if (queue === undefined) return;\n this.stepQueue.delete(id);\n await this.admission.release(queue, id);\n }\n\n /** In-memory await path for a remote step with a liveness `timeoutMs` (re-dispatch on timeout). */\n private async callRemoteInMemory<TInput, TOutput>(\n runId: string,\n seq: number,\n step: RemoteStepDef<TInput, TOutput>,\n input: TInput,\n transport?: string,\n ): Promise<TOutput> {\n if (this.pool.size === 0) throw new Error('remote steps require a Transport');\n const validInput = step.input.parse(input);\n const id = stepId(runId, seq);\n const enqueuedAt = new Date();\n this.emit({ type: 'step.started', runId, seq, name: step.name, kind: 'remote' });\n // Retry policy differs from a LOCAL step on purpose: a local `ctx.step` retries any non-fatal\n // throw (the work is in-process), but a remote step only re-dispatches on a liveness TIMEOUT\n // (presumed-dead worker). A worker that *reported* an error returned a deterministic verdict, so\n // we surface it to the workflow instead of hammering the worker. Timeout retries need a window\n // to detect death, so they're gated on `timeoutMs` being set.\n const maxAttempts = step.timeoutMs ? Math.max(1, step.retries ?? 1) : 1;\n\n for (let attempt = 1; ; attempt += 1) {\n const resultPromise = new Promise<RemoteResolution>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n });\n await this.pool.dispatch(\n {\n runId,\n seq,\n name: step.name,\n stepId: id,\n group: step.group,\n input: validInput,\n traceparent: this.traceparent?.(),\n context: this.context?.(),\n attempt,\n },\n transport,\n );\n try {\n const resolution = step.timeoutMs\n ? await this.awaitWithHeartbeat(id, resultPromise, step.timeoutMs)\n : await resultPromise;\n const output = step.output.parse(resolution.output) as TOutput;\n // The worker reports when it actually picked the task up; fall back to dispatch time if a\n // transport doesn't carry it (queue-wait then reads as zero rather than going negative).\n const startedAt = resolution.startedAt ? new Date(resolution.startedAt) : enqueuedAt;\n await this.completeStep({\n runId,\n seq,\n name: step.name,\n kind: 'remote',\n input: validInput,\n output,\n events: resolution.events,\n attempts: attempt,\n workerGroup: step.group,\n enqueuedAt,\n startedAt,\n });\n return output;\n } catch (err) {\n this.pending.delete(id);\n if (err instanceof RemoteStepTimeout && attempt < maxAttempts) continue;\n throw err;\n }\n }\n }\n\n /**\n * Await a remote result, but reject with `RemoteStepTimeout` if neither the result nor a heartbeat\n * arrives within `timeoutMs`. Each heartbeat (delivered via `transport.onHeartbeat`) rearms the\n * window, so a worker that keeps beating stays alive past `timeoutMs`.\n */\n private awaitWithHeartbeat(\n id: string,\n resultPromise: Promise<RemoteResolution>,\n timeoutMs: number,\n ): Promise<RemoteResolution> {\n return new Promise<RemoteResolution>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout>;\n const cleanup = () => {\n clearTimeout(timer);\n this.heartbeatResets.delete(id);\n };\n const arm = () => {\n timer = setTimeout(() => {\n cleanup();\n this.pending.delete(id);\n reject(new RemoteStepTimeout(id, timeoutMs));\n }, timeoutMs);\n (timer as { unref?: () => void }).unref?.();\n };\n this.heartbeatResets.set(id, () => {\n clearTimeout(timer);\n arm();\n });\n arm();\n resultPromise.then(\n (value) => {\n cleanup();\n resolve(value);\n },\n (err) => {\n cleanup();\n reject(err);\n },\n );\n });\n }\n}\n\n/** Raised inside the workflow when a remote worker reports a step failure. */\nexport class RemoteStepError extends Error {\n readonly stepError?: StepError | undefined;\n constructor(stepError?: StepError) {\n super(stepError?.message ?? 'remote step failed');\n this.name = 'RemoteStepError';\n this.stepError = stepError;\n }\n}\n","import type { z } from 'zod';\nimport type { RemoteStepDef, StepOptions } from './interfaces';\n\nexport interface RemoteStepConfig<TInput, TOutput> extends StepOptions {\n name: string;\n /** Worker group expected to handle this step. Defaults to the `name` prefix before the first dot. */\n group?: string;\n input: z.ZodType<TInput>;\n output: z.ZodType<TOutput>;\n}\n\n/**\n * Defines a typed handle to a step that runs on a remote worker. Call it from a workflow with\n * `ctx.call(step, input)`; a worker registers a handler under the same `name`.\n */\nexport function remoteStep<TInput, TOutput>(\n config: RemoteStepConfig<TInput, TOutput>,\n): RemoteStepDef<TInput, TOutput> {\n return {\n ...config,\n group: config.group ?? config.name.split('.')[0] ?? config.name,\n __remote: true,\n };\n}\n","import { RemoteWorkflowTimeout } from './errors';\nimport type {\n HistoryEvent,\n Transport,\n WorkflowDecision,\n WorkflowExecutor,\n WorkflowRun,\n WorkflowTask,\n} from './interfaces';\n\nlet taskCounter = 0;\n\n/**\n * A {@link WorkflowExecutor} backed by a {@link Transport}: it advances a remote workflow by\n * dispatching a {@link WorkflowTask} over the broker and awaiting the matching {@link WorkflowDecision}\n * (correlated by `taskId`). Pass one to `engine.registerRemote(name, version, { group, executor })` so\n * a workflow authored in another SDK (e.g. the Python `durable-worker`) is driven over Redis/BullMQ.\n *\n * Recovery-safe: if the engine crashes awaiting a decision, the re-drive dispatches a fresh task with\n * the same history — the worker's replay is deterministic, so it returns the same decision; a late\n * decision for the old `taskId` simply finds no waiter and is dropped.\n */\nexport class RemoteWorkflowExecutor implements WorkflowExecutor {\n private readonly pending = new Map<string, (decision: WorkflowDecision) => void>();\n private subscribed = false;\n\n constructor(\n private readonly transport: Transport,\n private readonly group: string,\n private readonly opts: { timeoutMs?: number } = {},\n ) {}\n\n private ensureSubscribed(): void {\n if (this.subscribed) return;\n if (!this.transport.onDecision) {\n throw new Error('transport does not support workflow decisions (onDecision)');\n }\n this.subscribed = true;\n this.transport.onDecision(async (decision) => {\n const resolve = this.pending.get(decision.taskId);\n if (resolve) {\n this.pending.delete(decision.taskId);\n resolve(decision);\n }\n });\n }\n\n async advance(run: WorkflowRun, history: HistoryEvent[]): Promise<WorkflowDecision> {\n if (!this.transport.dispatchWorkflowTask) {\n throw new Error('transport does not support workflow tasks (dispatchWorkflowTask)');\n }\n this.ensureSubscribed();\n taskCounter += 1;\n const taskId = `${run.id}:wf:${taskCounter}`;\n const task: WorkflowTask = {\n taskId,\n runId: run.id,\n workflow: run.workflow,\n workflowVersion: run.workflowVersion,\n input: run.input,\n history,\n group: this.group,\n priority: run.priority,\n attempt: 1,\n };\n const decision = new Promise<WorkflowDecision>((resolve, reject) => {\n this.pending.set(taskId, resolve);\n const { timeoutMs } = this.opts;\n if (timeoutMs) {\n const timer = setTimeout(() => {\n this.pending.delete(taskId);\n // A RECOVERABLE timeout, not a run failure: the decision may merely have been dropped while\n // the work completed. The engine catches this distinct type and re-drives via recovery\n // instead of failing the run. See RemoteWorkflowTimeout for the (opt-in) hazard note.\n reject(new RemoteWorkflowTimeout(taskId, timeoutMs));\n }, timeoutMs);\n (timer as { unref?: () => void }).unref?.();\n }\n });\n await this.transport.dispatchWorkflowTask(task);\n return decision;\n }\n}\n","import type { RunQuery, SignalWaiter, StateStore, StepCheckpoint, WorkflowRun } from './interfaces';\n\n/**\n * Transforms a payload value as it crosses the store boundary — e.g. encrypt-at-rest, compress, or\n * redact PII. `decode` must be the exact inverse of `encode`. Both are synchronous (use a local\n * cipher / codec); wrap an async KMS yourself if you need one.\n */\nexport interface PayloadCodec {\n encode(value: unknown): unknown;\n decode(value: unknown): unknown;\n}\n\n/**\n * A `StateStore` decorator that runs run/step **payloads** (input + output) through a\n * {@link PayloadCodec} — encoded on write, decoded on read — so they're never stored in the clear.\n * Adapter-agnostic: wrap any store. Searchable metadata (id, status, workflow, tags, timestamps) and\n * the structured `error` are left untouched so the dashboard, queries, and recovery still work.\n *\n * ```ts\n * const store = new CodecStateStore(new TypeOrmStateStore(ds), aesCodec);\n * ```\n */\nexport class CodecStateStore implements StateStore {\n constructor(\n private readonly inner: StateStore,\n private readonly codec: PayloadCodec,\n ) {}\n\n private enc(v: unknown): unknown {\n return v === undefined ? undefined : this.codec.encode(v);\n }\n private dec(v: unknown): unknown {\n return v === undefined ? undefined : this.codec.decode(v);\n }\n\n private encRun(run: WorkflowRun): WorkflowRun {\n return { ...run, input: this.enc(run.input), output: this.enc(run.output) };\n }\n private decRun<T extends WorkflowRun | null>(run: T): T {\n return (run && { ...run, input: this.dec(run.input), output: this.dec(run.output) }) as T;\n }\n private encCp(cp: StepCheckpoint): StepCheckpoint {\n return { ...cp, input: this.enc(cp.input), output: this.enc(cp.output) };\n }\n private decCp<T extends StepCheckpoint | null>(cp: T): T {\n return (cp && { ...cp, input: this.dec(cp.input), output: this.dec(cp.output) }) as T;\n }\n\n ensureSchema(): Promise<void> {\n return this.inner.ensureSchema?.() ?? Promise.resolve();\n }\n\n createRun(run: WorkflowRun): Promise<void> {\n return this.inner.createRun(this.encRun(run));\n }\n updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void> {\n const next = { ...patch };\n if ('input' in patch) next.input = this.enc(patch.input);\n if ('output' in patch) next.output = this.enc(patch.output);\n return this.inner.updateRun(runId, next);\n }\n async getRun(runId: string): Promise<WorkflowRun | null> {\n return this.decRun(await this.inner.getRun(runId));\n }\n deleteRun(runId: string): Promise<void> {\n return this.inner.deleteRun(runId);\n }\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n return this.decCp(await this.inner.getCheckpoint(runId, seq));\n }\n saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n return this.inner.saveCheckpoint(this.encCp(checkpoint));\n }\n transaction<T>(\n work: (tx: {\n raw: unknown;\n saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;\n }) => Promise<T>,\n ): Promise<T> {\n if (!this.inner.transaction) {\n throw new Error('the wrapped store does not support transactions');\n }\n // Encode the checkpoint inside the tx, so payloads stay encoded at rest like the normal path.\n return this.inner.transaction((tx) =>\n work({ raw: tx.raw, saveCheckpoint: (cp) => tx.saveCheckpoint(this.encCp(cp)) }),\n );\n }\n async listIncompleteRuns(): Promise<WorkflowRun[]> {\n return (await this.inner.listIncompleteRuns()).map((r) => this.decRun(r));\n }\n async listPendingRuns(limit: number): Promise<WorkflowRun[]> {\n return (await this.inner.listPendingRuns(limit)).map((r) => this.decRun(r));\n }\n async listDueTimers(nowMs: number): Promise<WorkflowRun[]> {\n return (await this.inner.listDueTimers(nowMs)).map((r) => this.decRun(r));\n }\n tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean> {\n return this.inner.tryLockRun(runId, owner, leaseUntilMs, nowMs);\n }\n releaseRunLock(runId: string): Promise<void> {\n return this.inner.releaseRunLock(runId);\n }\n renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n return this.inner.renewRunLock(runId, owner, leaseUntilMs);\n }\n putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n return this.inner.putSignalWaiter(waiter);\n }\n takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n return this.inner.takeSignalWaiter(token);\n }\n listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n return this.inner.listSignalWaiters(prefix);\n }\n bufferSignal(token: string, payload: unknown): Promise<void> {\n return this.inner.bufferSignal(token, this.enc(payload));\n }\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n const buffered = await this.inner.takeBufferedSignal(token);\n return buffered && { payload: this.dec(buffered.payload) };\n }\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n return (await this.inner.listRuns(query)).map((r) => this.decRun(r));\n }\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n return (await this.inner.listCheckpoints(runId)).map((c) => this.decCp(c));\n }\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n // Forward the targeted read when the inner store implements it; otherwise fall back to the\n // (always-present) listCheckpoints scan so wrapping a legacy custom store keeps working.\n if (this.inner.getLatestCheckpointByName) {\n const cp = await this.inner.getLatestCheckpointByName(runId, name);\n return cp ? this.decCp(cp) : undefined;\n }\n let latest: StepCheckpoint | undefined;\n for (const cp of await this.inner.listCheckpoints(runId)) if (cp.name === name) latest = cp;\n return latest ? this.decCp(latest) : undefined;\n }\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n const matches = this.inner.listCheckpointsByNamePrefix\n ? await this.inner.listCheckpointsByNamePrefix(runId, prefixes)\n : (await this.inner.listCheckpoints(runId)).filter((cp) =>\n prefixes.some((p) => cp.name.startsWith(p)),\n );\n return matches.map((c) => this.decCp(c));\n }\n}\n","import type { EngineEvent } from './interfaces';\n\nexport interface MetricsSnapshot {\n runs: { started: number; completed: number; failed: number; suspended: number };\n steps: { started: number; completed: number; failed: number };\n /** Per-workflow run counters, keyed by workflow name. */\n byWorkflow: Record<string, { started: number; completed: number; failed: number }>;\n /** Sum + count of recorded step durations (ms), for an average. */\n stepDuration: { sumMs: number; count: number };\n}\n\nexport interface MetricsCollector {\n snapshot(): MetricsSnapshot;\n /** Prometheus text exposition of the counters — serve this from a `/metrics` endpoint. */\n prometheus(): string;\n /** Unsubscribe from the engine. */\n stop(): void;\n}\n\ntype Subscribable = { subscribe(listener: (event: EngineEvent) => void): () => void };\n\n/**\n * Subscribe to an engine's lifecycle events and accumulate Prometheus-style counters (runs + steps by\n * outcome, per-workflow run counts, step-duration sum/count). Dependency-free — call `.prometheus()`\n * from your metrics endpoint, or `.snapshot()` for the raw numbers. Counters are per process; scrape\n * each instance.\n */\nexport function collectMetrics(engine: Subscribable): MetricsCollector {\n const m: MetricsSnapshot = {\n runs: { started: 0, completed: 0, failed: 0, suspended: 0 },\n steps: { started: 0, completed: 0, failed: 0 },\n byWorkflow: {},\n stepDuration: { sumMs: 0, count: 0 },\n };\n const wf = (name?: string) => {\n const k = name ?? 'unknown';\n let entry = m.byWorkflow[k];\n if (!entry) {\n entry = { started: 0, completed: 0, failed: 0 };\n m.byWorkflow[k] = entry;\n }\n return entry;\n };\n\n const stop = engine.subscribe((e) => {\n switch (e.type) {\n case 'run.started':\n m.runs.started += 1;\n wf(e.workflow).started += 1;\n break;\n case 'run.completed':\n m.runs.completed += 1;\n wf(e.workflow).completed += 1;\n break;\n case 'run.failed':\n m.runs.failed += 1;\n wf(e.workflow).failed += 1;\n break;\n case 'run.suspended':\n m.runs.suspended += 1;\n break;\n case 'step.started':\n m.steps.started += 1;\n break;\n case 'step.completed':\n m.steps.completed += 1;\n if (e.durationMs != null) {\n m.stepDuration.sumMs += e.durationMs;\n m.stepDuration.count += 1;\n }\n break;\n case 'step.failed':\n m.steps.failed += 1;\n break;\n }\n });\n\n return {\n snapshot: () => structuredClone(m),\n stop,\n prometheus: () => {\n const lines: string[] = [];\n lines.push('# TYPE durable_runs_total counter');\n for (const [k, v] of Object.entries(m.runs))\n lines.push(`durable_runs_total{event=\"${k}\"} ${v}`);\n lines.push('# TYPE durable_steps_total counter');\n for (const [k, v] of Object.entries(m.steps))\n lines.push(`durable_steps_total{event=\"${k}\"} ${v}`);\n lines.push('# TYPE durable_runs_by_workflow_total counter');\n for (const [name, v] of Object.entries(m.byWorkflow))\n for (const [event, n] of Object.entries(v))\n lines.push(`durable_runs_by_workflow_total{workflow=\"${name}\",event=\"${event}\"} ${n}`);\n lines.push('# TYPE durable_step_duration_ms_sum counter');\n lines.push(`durable_step_duration_ms_sum ${m.stepDuration.sumMs}`);\n lines.push('# TYPE durable_step_duration_count counter');\n lines.push(`durable_step_duration_count ${m.stepDuration.count}`);\n return `${lines.join('\\n')}\\n`;\n },\n };\n}\n","import { createRequire } from 'node:module';\nimport type { WorkflowEngine } from './engine';\n\n// Resolve the optional `cron-parser` peer dependency in a way that works in BOTH the ESM and CJS\n// builds of this package (dual publish). `createRequire(import.meta.url)` gives a real `require` in\n// ESM output; in the CJS build, tsup's banner shims `import.meta.url` to the file URL, so the same\n// call resolves there too. This keeps the load synchronous (no async leak into the scheduler API).\nconst nodeRequire = createRequire(import.meta.url);\n\nexport interface ScheduledWorkflow {\n /** Stable key identifying this schedule — part of the deterministic run id. */\n key: string;\n workflow: string;\n input?: unknown;\n /** Start one run every `everyMs`. Mutually exclusive with `cron`. */\n everyMs?: number;\n /**\n * A cron expression (5 fields `m h dom mon dow`, or 6 with leading seconds) evaluated in\n * {@link ScheduledWorkflow.timezone}. Mutually exclusive with `everyMs`. Needs the optional peer\n * dependency `cron-parser`.\n */\n cron?: string;\n /** IANA timezone the `cron` fires in (e.g. `America/Sao_Paulo`). Defaults to UTC. */\n timezone?: string;\n /** Temporarily stop firing this schedule (kept registered). Defaults to false. */\n paused?: boolean;\n /**\n * What to do when the previous window's run hasn't finished yet (fixed-interval schedules only):\n * `'allow'` (default) starts the new window anyway; `'skip'` skips it while the prior run is still\n * `running`/`suspended`, so a slow run can't pile up overlapping executions.\n */\n overlap?: 'allow' | 'skip';\n /**\n * Randomly delay the dispatch by up to this many ms BEFORE firing, to spread load when many\n * instances tick on the same boundary (avoids a thundering herd). Opt-in; absent = fire immediately.\n *\n * This is dispatch-path jitter only — it does NOT affect the run id (still the time bucket), so\n * idempotency is unchanged: two instances jittering the same window still start it exactly once.\n * (The engine forbids `Math.random` inside workflow code; the scheduler dispatch path is not\n * workflow code, so jitter here is fine.)\n */\n jitter?: number;\n /**\n * Enqueue windows that were missed while the scheduler was down, instead of silently skipping\n * them. Opt-in; absent = only the current window fires. `maxCatchup` bounds how many PRIOR windows\n * are backfilled (a long outage can't flood the system). Backfilled runs use each missed window's\n * deterministic bucket run id, so `engine.start` idempotency skips any that already ran.\n */\n backfill?: { maxCatchup: number };\n}\n\n/** Injectable dispatch-path effects (kept out of the deterministic run-id logic). Defaults to real\n * `Math.random` + `setTimeout`; overridden in tests so jitter is deterministic and instant. */\nexport interface RunSchedulesOptions {\n random?: () => number;\n sleep?: (ms: number) => Promise<void>;\n}\n\nconst defaultSleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\n/** Deterministic run id for a fixed-interval schedule's current time window. */\nexport function scheduledRunId(key: string, everyMs: number, nowMs: number): string {\n return `sched:${key}:${Math.floor(nowMs / everyMs)}`;\n}\n\ntype CronParser = typeof import('cron-parser');\nlet cronParser: CronParser | undefined;\nfunction loadCronParser(): CronParser {\n if (cronParser) return cronParser;\n try {\n // Lazy + optional: core stays dependency-free; only users who schedule by cron need this.\n cronParser = nodeRequire('cron-parser') as CronParser;\n } catch {\n throw new Error(\n 'cron schedules need the optional peer dependency \"cron-parser\" — install it (e.g. `npm i cron-parser`).',\n );\n }\n return cronParser;\n}\n\n/**\n * Epoch ms of the most recent cron fire at or before `nowMs`, evaluated in `timezone` (default UTC).\n * This is the deterministic \"bucket\" a cron run is keyed on, so polling repeatedly within an\n * interval resolves to the same fire time — and thus the same idempotent run id.\n */\nexport function prevCronFireMs(expr: string, nowMs: number, timezone = 'UTC'): number {\n const parser = loadCronParser();\n // `+1` makes a fire landing exactly on `nowMs` count as \"at or before now\", not the prior one.\n const it = parser.parseExpression(expr, { currentDate: new Date(nowMs + 1), tz: timezone });\n return it.prev().toDate().getTime();\n}\n\n/** The deterministic, idempotent run id for a schedule at `nowMs` — its current fire window. */\nfunction scheduleRunIdAt(s: ScheduledWorkflow, nowMs: number): string {\n if (s.cron != null) return `sched:${s.key}:${prevCronFireMs(s.cron, nowMs, s.timezone)}`;\n if (s.everyMs != null) return scheduledRunId(s.key, s.everyMs, nowMs);\n throw new Error(`schedule \"${s.key}\" needs either \"everyMs\" or \"cron\"`);\n}\n\n/**\n * The run ids this schedule should fire at `nowMs`: the current window, plus — when `backfill` is set\n * — up to `maxCatchup` prior windows that may have been missed. Oldest-first, so a backfill catches\n * up in chronological order. Ids are the same deterministic buckets `scheduleRunIdAt` produces, so\n * `engine.start` idempotency drops any window that already ran.\n */\nfunction scheduleRunIdsAt(s: ScheduledWorkflow, nowMs: number): string[] {\n const current = scheduleRunIdAt(s, nowMs);\n if (!s.backfill || s.backfill.maxCatchup <= 0) return [current];\n\n const ids: string[] = [];\n if (s.everyMs != null) {\n const bucket = Math.floor(nowMs / s.everyMs);\n const oldest = Math.max(0, bucket - s.backfill.maxCatchup);\n for (let b = oldest; b < bucket; b += 1) ids.push(`sched:${s.key}:${b}`);\n } else if (s.cron != null) {\n // Walk back through prior cron fire times (most-recent missed first), then reverse to oldest-first.\n const prior: string[] = [];\n let cursor = prevCronFireMs(s.cron, nowMs, s.timezone);\n for (let i = 0; i < s.backfill.maxCatchup; i += 1) {\n // `cursor` (exclusive) → the fire strictly before it.\n const before = prevCronFireMs(s.cron, cursor - 1, s.timezone);\n prior.push(`sched:${s.key}:${before}`);\n cursor = before;\n }\n ids.push(...prior.reverse());\n }\n ids.push(current);\n return ids;\n}\n\n/**\n * Start each schedule's current-window run. The run id is the time bucket (a fixed-interval index,\n * or the cron fire time) and `engine.start` is idempotent, so firing this on an interval — or\n * racing two instances on the same tick — starts **each window exactly once**. Wire it to a\n * `setInterval`, the durable timer poller, or `@nestjs/schedule`. Returns the run ids for the\n * current windows.\n */\nexport async function runSchedules(\n engine: Pick<WorkflowEngine, 'start' | 'getRun'>,\n schedules: readonly ScheduledWorkflow[],\n nowMs: number,\n opts?: RunSchedulesOptions,\n): Promise<string[]> {\n const random = opts?.random ?? Math.random;\n const sleep = opts?.sleep ?? defaultSleep;\n const ids: string[] = [];\n for (const s of schedules) {\n if (s.paused) continue;\n // overlap:'skip' (fixed-interval): don't start this window while the previous window's run is\n // still in-flight, so a slow run can't pile up. Interval-only — cron windows aren't adjacent ids.\n if (s.overlap === 'skip' && s.everyMs) {\n const prevBucket = Math.floor(nowMs / s.everyMs) - 1;\n if (prevBucket >= 0) {\n const prev = await engine.getRun(`sched:${s.key}:${prevBucket}`);\n if (prev && (prev.status === 'running' || prev.status === 'suspended')) continue;\n }\n }\n // Dispatch-path jitter (not workflow code): spread same-boundary ticks across instances. Applied\n // once per schedule, before firing — the run ids below are unaffected, so idempotency holds.\n if (s.jitter && s.jitter > 0) await sleep(Math.floor(random() * s.jitter));\n for (const runId of scheduleRunIdsAt(s, nowMs)) {\n await engine.start(s.workflow, s.input, runId);\n ids.push(runId);\n }\n }\n return ids;\n}\n","import type { AttributeFilter, AttributeOp, RunQuery, WorkflowRun } from './interfaces';\nimport type { SearchAttributes } from './interfaces';\n\n/** Compare one attribute value against a filter operand. Range ops need both sides comparable. */\nfunction compare(actual: unknown, op: AttributeOp, expected: string | number | boolean): boolean {\n switch (op) {\n case 'eq':\n return actual === expected;\n case 'ne':\n return actual !== expected;\n case 'gt':\n return actual != null && actual > expected;\n case 'gte':\n return actual != null && actual >= expected;\n case 'lt':\n return actual != null && actual < expected;\n case 'lte':\n return actual != null && actual <= expected;\n }\n}\n\n/**\n * Does a run's search attributes satisfy EVERY filter (AND)? A missing key never matches (so `ne`\n * on an absent key is false too — the attribute simply isn't there to compare). Empty/undefined\n * filters match everything. Shared by every store so typed/range queries behave identically across\n * adapters (applied in-process after the coarse workflow/status/tag filters).\n */\nexport function matchesAttributes(\n attributes: SearchAttributes | undefined,\n filters: AttributeFilter[] | undefined,\n): boolean {\n if (!filters?.length) return true;\n if (!attributes) return false;\n return filters.every((f) => f.key in attributes && compare(attributes[f.key], f.op, f.value));\n}\n\n/**\n * Apply a query's attribute predicates then its `offset`/`limit`, in-process — for store adapters\n * that can't express typed/range predicates in SQL. Pass rows already coarse-filtered (workflow /\n * status / tag) and sorted newest-first; this filters by `attributes` and paginates. Only call it\n * when `query.attributes` is set (otherwise let the DB do `LIMIT`/`OFFSET`).\n */\nexport function applyAttributeQuery(rows: WorkflowRun[], query: RunQuery): WorkflowRun[] {\n const filtered = rows.filter((r) => matchesAttributes(r.searchAttributes, query.attributes));\n const offset = query.offset ?? 0;\n const limit = query.limit ?? filtered.length;\n return filtered.slice(offset, offset + limit);\n}\n\n/**\n * One normalized row of the `durable_run_attributes` side-table: a single (key → value) pair of a\n * run's search attributes, split into typed columns so SQL can index/range-scan it. Exactly one of\n * `strValue`/`numValue` is set per row (booleans normalize to a string `\"true\"`/`\"false\"` so `eq`/`ne`\n * still match). NULL for the column that doesn't apply, which keeps `(key, numValue)` /\n * `(key, strValue)` indexes selective.\n */\nexport interface RunAttributeRow {\n runId: string;\n key: string;\n strValue: string | null;\n numValue: number | null;\n}\n\n/**\n * Explode a run's search attributes into normalized side-table rows (one per key). Used by SQL stores\n * to maintain `durable_run_attributes` on every create/update and by the in-memory store's index, so\n * attribute predicates can be pushed DOWN into a join/EXISTS instead of scanned in-process. Numbers go\n * to `numValue`; strings to `strValue`; booleans to `strValue` as `\"true\"`/`\"false\"` (matching how the\n * in-process `compare` treats `eq`/`ne` on booleans). Returns `[]` for a run with no attributes.\n */\nexport function normalizeAttributeRows(\n runId: string,\n attributes: SearchAttributes | undefined,\n): RunAttributeRow[] {\n if (!attributes) return [];\n const out: RunAttributeRow[] = [];\n for (const [key, value] of Object.entries(attributes)) {\n if (typeof value === 'number') {\n out.push({ runId, key, strValue: null, numValue: value });\n } else if (typeof value === 'boolean') {\n out.push({ runId, key, strValue: value ? 'true' : 'false', numValue: null });\n } else {\n out.push({ runId, key, strValue: value, numValue: null });\n }\n }\n return out;\n}\n\n/** SQL comparison operator for an {@link AttributeOp} (used to build pushdown predicates). */\nexport function sqlComparator(op: AttributeOp): string {\n switch (op) {\n case 'eq':\n return '=';\n case 'ne':\n return '<>';\n case 'gt':\n return '>';\n case 'gte':\n return '>=';\n case 'lt':\n return '<';\n case 'lte':\n return '<=';\n }\n}\n\n/**\n * Which side-table column an attribute filter compares against: numeric operands (and range ops on\n * numbers) hit `numValue`; everything else hits `strValue` (booleans are stored as `\"true\"`/`\"false\"`).\n * Keeping this in core means every SQL adapter pushes predicates down identically.\n */\nexport function attributeColumnFor(filter: AttributeFilter): 'numValue' | 'strValue' {\n return typeof filter.value === 'number' ? 'numValue' : 'strValue';\n}\n\n/** The literal a side-table predicate compares against (booleans → `\"true\"`/`\"false\"` strings). */\nexport function attributeOperand(filter: AttributeFilter): string | number {\n if (typeof filter.value === 'boolean') return filter.value ? 'true' : 'false';\n return filter.value;\n}\n","/**\n * Dependency-injection tokens. Adapters bind their implementations to these so `core` and\n * `@dudousxd/nestjs-durable` depend only on the interfaces in `./interfaces`.\n *\n * These use `Symbol.for(key)` (the global symbol registry), NOT `Symbol(key)`, so the token is the\n * SAME instance no matter how many times `core` is evaluated in a process. A consumer can hold more\n * than one physical copy of `core` at runtime — pnpm peer-dependency multiplexing installs a\n * separate virtual copy per distinct peer set, and the dual ESM/CJS build can be loaded once as\n * `import` (`index.js`) and once as `require` (`index.cjs`). A plain `Symbol()` would mint a\n * DISTINCT token per copy, so `DurableModule` (provider) and `DashboardService` / a store adapter\n * (injector) could resolve different symbols → Nest can't satisfy the dependency\n * (`STATE_STORE is not available in the DurableApiModule context`). A registered symbol collapses\n * them to one. Mirrors the `CONTEXT_ACCESSOR` token in `@dudousxd/nestjs-durable`'s `tokens.ts`.\n */\n\n/**\n * @deprecated Use {@link STATE_STORE_CANONICAL} (`@dudousxd/nestjs-durable:state-store`). The legacy\n * token stays bound as a back-compat alias and still resolves; it will be removed in a future major.\n */\nexport const STATE_STORE = Symbol.for('nestjs-durable:STATE_STORE');\n/**\n * @deprecated Use {@link TRANSPORT_CANONICAL} (`@dudousxd/nestjs-durable:transport`). The legacy\n * token stays bound as a back-compat alias and still resolves; it will be removed in a future major.\n */\nexport const TRANSPORT = Symbol.for('nestjs-durable:TRANSPORT');\n/**\n * @deprecated Use {@link DURABLE_OPTIONS_CANONICAL} (`@dudousxd/nestjs-durable:options`). The legacy\n * token stays bound as a back-compat alias and still resolves; it will be removed in a future major.\n */\nexport const DURABLE_OPTIONS = Symbol.for('nestjs-durable:DURABLE_OPTIONS');\n\n/**\n * Canonical, cross-lib-discoverable aliases of the durable DI tokens, following the ecosystem\n * capability naming `@dudousxd/nestjs-durable:<name>` (identical to `capability('durable', <name>)`).\n * `DurableModule` binds these alongside the legacy tokens (dual-bind), so an external library can\n * resolve durable's store/transport/options by the canonical name without importing durable\n * internals. Bare `Symbol.for` (same cross-copy-stability rationale as the legacy tokens above)\n * keeps `core` free of any `@dudousxd/nestjs-diagnostics` runtime dependency.\n */\nexport const STATE_STORE_CANONICAL = Symbol.for('@dudousxd/nestjs-durable:state-store');\nexport const TRANSPORT_CANONICAL = Symbol.for('@dudousxd/nestjs-durable:transport');\nexport const DURABLE_OPTIONS_CANONICAL = Symbol.for('@dudousxd/nestjs-durable:options');\n","import type {\n RunQuery,\n SignalWaiter,\n StateStore,\n StepCheckpoint,\n WorkflowRun,\n} from '../interfaces';\nimport type { AttributeFilter } from '../interfaces';\nimport { type RunAttributeRow, normalizeAttributeRows } from '../search-attributes';\n\n/**\n * A non-durable, in-process `StateStore` for tests and local development.\n * The shipped `@dudousxd/nestjs-durable-store` package re-exports an equivalent.\n */\nexport class InMemoryStateStore implements StateStore {\n private readonly runs = new Map<string, WorkflowRun>();\n private readonly checkpoints = new Map<string, StepCheckpoint>();\n private readonly signalWaiters = new Map<string, SignalWaiter>();\n\n /**\n * Normalized search-attribute side-table, the in-memory analog of the SQL stores'\n * `durable_run_attributes`: `key -> (runId -> row)`. Maintained on every create/update so an\n * attribute query can be pushed DOWN to a key-indexed candidate set instead of scanning every run\n * and comparing in-process. Mirrors {@link normalizeAttributeRows} so behavior matches the SQL path.\n */\n private readonly attributeIndex = new Map<string, Map<string, RunAttributeRow>>();\n /** Test/observability hook: how many candidate runs the last attribute query's index produced. */\n lastAttributeCandidates = 0;\n /**\n * Test/observability hook: how many checkpoint rows the LAST checkpoint read materialized (the rows\n * actually returned to the caller). `listCheckpoints` returns all rows for the run; the targeted\n * {@link getLatestCheckpointByName} / {@link listCheckpointsByNamePrefix} return only the matches —\n * so this lets the benchmark contrast \"fetch N, scan in JS\" against \"fetch the k that match\".\n */\n lastCheckpointRowsRead = 0;\n\n private key(runId: string, seq: number): string {\n return `${runId}:${seq}`;\n }\n\n /** Drop then re-add a run's normalized attribute rows so the index tracks its current attributes. */\n private reindexAttributes(runId: string, attributes: WorkflowRun['searchAttributes']): void {\n for (const byRun of this.attributeIndex.values()) byRun.delete(runId);\n for (const row of normalizeAttributeRows(runId, attributes)) {\n let byRun = this.attributeIndex.get(row.key);\n if (!byRun) {\n byRun = new Map();\n this.attributeIndex.set(row.key, byRun);\n }\n byRun.set(runId, row);\n }\n }\n\n async createRun(run: WorkflowRun): Promise<void> {\n this.runs.set(run.id, { ...run });\n this.reindexAttributes(run.id, run.searchAttributes);\n }\n\n async updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void> {\n const existing = this.runs.get(runId);\n if (!existing) throw new Error(`run ${runId} not found`);\n const next = { ...existing, ...patch };\n this.runs.set(runId, next);\n if ('searchAttributes' in patch) this.reindexAttributes(runId, next.searchAttributes);\n }\n\n async getRun(runId: string): Promise<WorkflowRun | null> {\n const run = this.runs.get(runId);\n return run ? { ...run } : null;\n }\n\n async deleteRun(runId: string): Promise<void> {\n this.runs.delete(runId);\n for (const [key, cp] of this.checkpoints) {\n if (cp.runId === runId) this.checkpoints.delete(key);\n }\n for (const [token, waiter] of this.signalWaiters) {\n if (waiter.runId === runId) this.signalWaiters.delete(token);\n }\n // Drop the run's normalized attribute rows (reindex with no attributes clears them).\n this.reindexAttributes(runId, undefined);\n }\n\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n const cp = this.checkpoints.get(this.key(runId, seq));\n return cp ? { ...cp } : null;\n }\n\n async saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n this.checkpoints.set(this.key(checkpoint.runId, checkpoint.seq), { ...checkpoint });\n }\n\n async listIncompleteRuns(): Promise<WorkflowRun[]> {\n return [...this.runs.values()].filter((r) => r.status === 'running').map((r) => ({ ...r }));\n }\n\n async listPendingRuns(limit: number): Promise<WorkflowRun[]> {\n return [...this.runs.values()]\n .filter((r) => r.status === 'pending')\n .sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime() || a.id.localeCompare(b.id))\n .slice(0, limit)\n .map((r) => ({ ...r }));\n }\n\n async listDueTimers(nowMs: number): Promise<WorkflowRun[]> {\n return [...this.runs.values()]\n .filter((r) => r.status === 'suspended' && r.wakeAt !== undefined && r.wakeAt <= nowMs)\n .map((r) => ({ ...r }));\n }\n\n async tryLockRun(\n runId: string,\n owner: string,\n leaseUntilMs: number,\n nowMs: number,\n ): Promise<boolean> {\n const run = this.runs.get(runId);\n if (!run) return false;\n if (run.lockedUntil !== undefined && run.lockedUntil > nowMs) return false;\n run.lockedBy = owner;\n run.lockedUntil = leaseUntilMs;\n return true;\n }\n\n async releaseRunLock(runId: string): Promise<void> {\n const run = this.runs.get(runId);\n if (run) {\n run.lockedBy = undefined;\n run.lockedUntil = undefined;\n }\n }\n\n async renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n const run = this.runs.get(runId);\n if (!run || run.lockedBy !== owner) return false;\n run.lockedUntil = leaseUntilMs;\n return true;\n }\n\n async putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n this.signalWaiters.set(waiter.token, { ...waiter });\n }\n\n async takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n const waiter = this.signalWaiters.get(token);\n if (!waiter) return null;\n this.signalWaiters.delete(token);\n return { ...waiter };\n }\n\n async listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n return [...this.signalWaiters.values()]\n .filter((w) => w.token.startsWith(prefix))\n .map((w) => ({ ...w }));\n }\n\n // No real DB transaction (there's no DB) — run the work and save the checkpoint. Exactly-once\n // across a crash needs a SQL store; this keeps `ctx.transaction` usable in tests / local dev.\n async transaction<T>(\n work: (tx: {\n raw: unknown;\n saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;\n }) => Promise<T>,\n ): Promise<T> {\n return work({ raw: this, saveCheckpoint: (cp) => this.saveCheckpoint(cp) });\n }\n\n private readonly bufferedSignals = new Map<string, unknown[]>();\n async bufferSignal(token: string, payload: unknown): Promise<void> {\n const queue = this.bufferedSignals.get(token) ?? [];\n queue.push(payload);\n this.bufferedSignals.set(token, queue);\n }\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n const queue = this.bufferedSignals.get(token);\n if (!queue || queue.length === 0) return null;\n const payload = queue.shift();\n if (queue.length === 0) this.bufferedSignals.delete(token);\n return { payload };\n }\n\n /**\n * Candidate run ids satisfying ONE attribute predicate, served from {@link attributeIndex} — the\n * pushdown step. Numeric predicates scan only `numValue` rows under the key; string/boolean ones\n * scan `strValue` rows. This is the in-memory analog of the SQL EXISTS on `durable_run_attributes`.\n */\n private candidatesForFilter(f: AttributeFilter): Set<string> {\n const byRun = this.attributeIndex.get(f.key);\n const out = new Set<string>();\n if (!byRun) return out;\n const numeric = typeof f.value === 'number';\n const operand = typeof f.value === 'boolean' ? (f.value ? 'true' : 'false') : f.value;\n for (const row of byRun.values()) {\n const actual = numeric ? row.numValue : row.strValue;\n if (actual == null) continue;\n let ok = false;\n switch (f.op) {\n case 'eq':\n ok = actual === operand;\n break;\n case 'ne':\n ok = actual !== operand;\n break;\n case 'gt':\n ok = actual > operand;\n break;\n case 'gte':\n ok = actual >= operand;\n break;\n case 'lt':\n ok = actual < operand;\n break;\n case 'lte':\n ok = actual <= operand;\n break;\n }\n if (ok) out.add(row.runId);\n }\n return out;\n }\n\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n let runs = [...this.runs.values()];\n if (query.workflow) runs = runs.filter((r) => r.workflow === query.workflow);\n if (query.status) runs = runs.filter((r) => r.status === query.status);\n if (query.statuses) runs = runs.filter((r) => query.statuses?.includes(r.status));\n if (query.tag) runs = runs.filter((r) => r.tags?.includes(query.tag as string));\n if (query.attributes?.length) {\n // Pushdown: intersect per-predicate candidate sets from the key-indexed side-table, so we only\n // ever materialize the runs that already satisfy EVERY attribute filter (no full per-run scan).\n let candidates: Set<string> | null = null;\n for (const f of query.attributes) {\n const next = this.candidatesForFilter(f);\n if (candidates == null) {\n candidates = next;\n } else {\n const prev: Set<string> = candidates;\n candidates = new Set([...prev].filter((id) => next.has(id)));\n }\n if (candidates.size === 0) break;\n }\n const ids = candidates ?? new Set<string>();\n this.lastAttributeCandidates = ids.size;\n runs = runs.filter((r) => ids.has(r.id));\n }\n // Newest first (matches the store adapters' `createdAt DESC`) — recent runs on top in the dashboard.\n runs.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n const offset = query.offset ?? 0;\n const limit = query.limit ?? runs.length;\n return runs.slice(offset, offset + limit).map((r) => ({ ...r }));\n }\n\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n const rows = [...this.checkpoints.values()]\n .filter((cp) => cp.runId === runId)\n .sort((a, b) => a.seq - b.seq)\n .map((cp) => ({ ...cp }));\n this.lastCheckpointRowsRead = rows.length;\n return rows;\n }\n\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n let latest: StepCheckpoint | undefined;\n for (const cp of this.checkpoints.values()) {\n if (cp.runId !== runId || cp.name !== name) continue;\n if (!latest || cp.seq > latest.seq) latest = cp;\n }\n this.lastCheckpointRowsRead = latest ? 1 : 0;\n return latest ? { ...latest } : undefined;\n }\n\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n const rows = [...this.checkpoints.values()]\n .filter((cp) => cp.runId === runId && prefixes.some((p) => cp.name.startsWith(p)))\n .sort((a, b) => a.seq - b.seq)\n .map((cp) => ({ ...cp }));\n this.lastCheckpointRowsRead = rows.length;\n return rows;\n }\n}\n","import type {\n ControlMessage,\n ControlPlane,\n Heartbeat,\n RemoteTask,\n StepResult,\n Transport,\n WorkflowStepEvent,\n} from '../interfaces';\nimport { type StepHandler, runStepHandler } from '../protocol';\n\n/**\n * An in-process `Transport` (and `ControlPlane`) for tests and local development: registered\n * handlers stand in for remote workers, so a whole cross-app workflow runs in a single process,\n * and control messages broadcast locally. Pass the same instance as both `transport` and\n * `controlPlane`.\n */\nexport class InMemoryTransport implements Transport, ControlPlane {\n private readonly handlers = new Map<string, StepHandler>();\n private resultHandler?: (result: StepResult) => Promise<void>;\n private stepEventHandler?: (event: WorkflowStepEvent) => Promise<void>;\n private readonly controlHandlers = new Set<(msg: ControlMessage) => void>();\n\n /** Register a fake worker handler for a step name. */\n handle(name: string, fn: StepHandler): void {\n this.handlers.set(name, fn);\n }\n\n async dispatch(task: RemoteTask): Promise<void> {\n if (!this.resultHandler) throw new Error('no result handler registered');\n const result = await runStepHandler(task, this.handlers.get(task.name));\n // Deliver the result ASYNCHRONOUSLY, not inline: a durable `ctx.call` suspends the run right\n // after dispatch, so the result must land AFTER that unwinds (else the resume re-enters\n // mid-suspend). Real brokers are async; this mirrors them.\n setImmediate(() => void this.resultHandler?.(result));\n }\n\n onResult(handler: (result: StepResult) => Promise<void>): void {\n this.resultHandler = handler;\n }\n\n onHeartbeat(_handler: (beat: Heartbeat) => Promise<void>): void {\n // In-process handlers run synchronously; there is no liveness to track.\n }\n\n /** Workflow step lifecycle: deliver to the engine's handler (async, mirroring a real broker). */\n async dispatchStepEvent(event: WorkflowStepEvent): Promise<void> {\n await this.stepEventHandler?.(event);\n }\n\n onStepEvent(handler: (event: WorkflowStepEvent) => Promise<void>): void {\n this.stepEventHandler = handler;\n }\n\n // Control plane: broadcast to every registered handler (including the publisher's own — the\n // engine dedupes by `from`), mirroring how a real broker echoes a publish to all subscribers.\n async publishControl(msg: ControlMessage): Promise<void> {\n for (const handler of this.controlHandlers) handler(msg);\n }\n\n onControl(handler: (msg: ControlMessage) => void): void {\n this.controlHandlers.add(handler);\n }\n}\n"],"mappings":"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","names":["QueueController","inFlight","windowStart","windowCount","waiters","Map","waiterSeq","keyServed","servedTick","config","clock","ordered","fairness","order","tryAdmit","item","now","rl","rateLimit","periodMs","limit","ok","retryAt","usingOrder","priority","waiterId","full","concurrency","register","retryMs","size","isNext","delete","key","set","release","existing","get","seq","self","undefined","Number","POSITIVE_INFINITY","best","w","values","better","a","b","sa","servedOf","sb","InMemoryAdmissionBackend","controllers","Map","clock","register","config","set","name","QueueController","handles","queue","has","tryAdmit","item","controller","get","ok","release","_slotId","UNIT_MS","ms","s","sec","second","seconds","m","min","minute","minutes","h","hr","hour","hours","d","day","days","w","week","weeks","parseDuration","duration","match","trim","Error","value","Number","unit","toLowerCase","factor","undefined","backoffDelay","attempt","options","base","backoffMs","raw","backoff","capped","backoffMaxMs","Math","min","jitter","round","random","withDuration","start","now","data","base","durationMs","createStepLogger","events","currentSub","push","level","message","at","subId","id","undefined","subEvent","e","status","phase","name","group","subProcess","body","opts","globalThis","crypto","randomUUID","prevSub","terminal","emit","handle","skip","reason","fail","result","err","Error","String","debug","m","d","info","warn","error","sub","stepId","runId","seq","breakpointToken","runStepHandler","task","handler","base","startedAt","Date","now","status","error","message","name","retryable","events","withEvents","result","length","output","input","createStepLogger","err","e","Error","String","code","nonEmptyEvents","events","length","undefined","stepCheckpoint","p","runId","seq","name","kind","stepId","status","input","output","error","attempts","workerGroup","wakeAt","parallelGroup","enqueuedAt","startedAt","finishedAt","instantCheckpoint","at","Date","FatalError","Error","code","message","name","SingletonQueueFullError","workflow","key","maxQueueDepth","SignalTimeoutError","token","timeoutMs","RemoteStepTimeout","stepId","RemoteWorkflowTimeout","taskId","NonDeterminismError","runId","seq","expected","recorded","GatherError","failures","total","ids","map","f","id","join","denom","length","WorkflowSuspended","wakeAt","ContinueAsNew","input","ENTITY_WORKFLOW","entityRunId","name","key","Entities","configs","Map","host","register","ctx","input","run","config","set","dispatch","op","arg","reply","runId","signalWithStart","token","payload","signal","getState","getEvent","get","FatalError","state","initialState","i","msg","waitForSignal","out","step","handler","handlers","result","setEvent","accToken","target","EventAccumulators","host","register","ctx","input","debounce","batch","route","config","payload","workflow","mode","windowMs","maxSize","signalWithStart","token","last","waitForSignal","timeoutMs","e","SignalTimeoutError","startChild","continueAsNew","events","deadline","now","length","remaining","push","enc","s","Buffer","from","toString","dec","eventPrefix","name","eventToken","match","runId","seq","JSON","stringify","eventMatchOf","token","parse","split","eventMatches","payload","keys","Object","length","p","every","k","SINGLETON_RETRY_MS","SINGLETON_RETRY_JITTER_MS","SingletonGate","deps","tag","cfg","input","key","retryWakeAt","clock","Math","floor","random","assertCapacity","workflow","maxQueueDepth","cap","limit","queued","store","listRuns","statuses","length","SingletonQueueFullError","admit","run","inflight","sort","a","b","createdAt","getTime","id","localeCompare","idx","findIndex","r","wakeNext","settled","configFor","tags","find","t","startsWith","gated","next","slice","wakeAt","updateRun","undefined","updatedAt","Date","catch","dispatch","TransportPool","transports","size","length","bind","onResult","onHeartbeat","onStepEvent","transport","dispatch","task","preferId","lastErr","id","ordered","err","Error","groupHealth","group","reports","push","undefined","depth","reduce","sum","r","liveWorkers","flatMap","listWorkerGroups","groups","Set","g","add","pref","filter","t","unwrapCompletion","payload","label","c","ok","FatalError","error","value","WORKFLOW_NAME_KEY","Symbol","for","workflowName","ref","name","Error","normalizeChildOptions","options","childId","Position","seq","next","rewind","createWorkflowCtx","host","runId","compensations","workflow","store","replay","pos","readCheckpoint","hit","get","undefined","getCheckpoint","writeCheckpoint","cp","saveCheckpoint","set","step","name","fn","current","existing","NonDeterminismError","status","compensate","push","output","maxAttempts","Math","max","retries","startedAt","Date","startStep","kind","attempts","enqueuedAt","attempt","events","invocation","stepName","body","createStepLogger","clock","interceptStep","completeStep","err","FatalError","failStep","error","message","Error","String","stack","wait","backoffDelay","Promise","resolve","setTimeout","transaction","tx","raw","instantCheckpoint","suspendUntil","wakeAt","now","WorkflowSuspended","at","sleep","duration","parseDuration","sleepUntil","when","getTime","continueAsNew","input","ContinueAsNew","consumeBuffered","token","buffered","takeBufferedSignal","payload","value","waitForSignal","opts","timeoutMs","putSignalWaiter","deadlineSeq","waitSeq","recorded","deadline","waited","takeSignalWaiter","catch","SignalTimeoutError","waitForEvent","eventToken","match","task","dispatch","unwrapCompletion","child","priority","id","getRun","startChild","workflowName","all","inputs","length","mode","positions","map","group","i","c","ok","GatherError","index","pending","parallelGroup","outputs","failures","callEntity","key","op","arg","reply","signalEntity","breakpoint","label","breakpointToken","patched","marker","startsWith","onUpdate","setEvent","webhook","url","webhookUrl","random","uuid","globalThis","crypto","randomUUID","call","remote","callRemote","queue","transport","fairnessKey","mergeTags","staticTags","runTags","length","undefined","Set","BREAKPOINT","isBreakpoint","cp","status","name","startsWith","versionKey","version","nextContinuationId","runId","m","match","Number","isNewerVersion","a","b","na","nb","isNaN","localeCompare","numeric","WorkflowEngine","store","pool","controlPlane","clock","instanceId","leaseMs","maxRecoveryAttempts","webhookUrl","traceparent","context","rehydrate","compensationRetries","trackStepStart","runDispatcher","singletons","workflows","Map","latest","eventTriggers","entities","accumulators","pending","heartbeatResets","listeners","interceptors","cancelListeners","enqueuedListeners","deadListeners","updateValidators","cancelRequested","admission","queueWaiters","stepQueue","inflight","draining","deps","TransportPool","transports","transport","id","Date","now","InMemoryAdmissionBackend","onFreed","queue","wakeQueueWaiters","globalThis","crypto","randomUUID","_carrier","fn","Math","max","dispatch","queueMicrotask","runOne","catch","SingletonGate","configFor","run","get","workflow","workflowVersion","singleton","bind","result","waiter","stepId","delete","resolve","output","startedAt","events","reject","RemoteStepError","error","completeRemoteResult","beat","event","persistStepEvent","onControl","msg","from","kind","deliver","at","notifyCancelled","EventAccumulators","Entities","registerEntity","config","register","signalEntity","key","op","arg","signal","getEntityState","getState","onEnqueued","listener","add","opts","registered","tags","executionTimeoutMs","executionTimeout","parseDuration","validateInput","onEvent","eventBatch","set","current","subscribers","registerRemote","Error","remote","group","executor","registerQueue","subscribe","use","interceptor","push","i","indexOf","splice","interceptStep","invocation","body","carrier","chain","reduceRight","next","onCancel","onDead","notifyDead","emit","full","publishControl","start","input","workflowName","prior","getRun","tag","assertCapacity","searchAttributes","priority","createdAt","updatedAt","createRun","resume","track","execute","p","finally","drain","timeoutMs","size","timer","Promise","t","setTimeout","unref","race","allSettled","sweepTimeouts","reg","values","deadline","listRuns","getTime","message","code","updateRun","type","recoverIncomplete","nowMs","results","listIncompleteRuns","acquired","tryLockRun","settled","countRecovery","releaseRunLock","attempts","recoveryAttempts","resumeDueTimers","resumeLeased","listDueTimers","requeue","retryWithInput","newRunId","slice","runPending","listPendingRuns","waitForRun","isSettled","s","toResult","done","off","finish","clearTimeout","check","then","ev","runs","onLocked","publishEvent","payload","touched","waiters","listSignalWaiters","eventPrefix","w","eventMatches","eventMatchOf","token","eventId","batch","route","takeSignalWaiter","bufferSignal","saveCheckpoint","instantCheckpoint","seq","signalWithStart","completeTask","ok","value","failTask","notifyParent","completion","cancel","compensate","cancelChildren","wakeNext","cancelWhere","filter","r","deleteRun","deleted","childId","getRunChildren","parentRunId","childIds","prefixes","childCheckpoints","listCheckpointsByNamePrefix","listCheckpoints","some","knownGroups","extra","groups","def","workerHealth","listWorkerGroups","out","health","groupHealth","phase","stepCheckpoint","enqueuedAt","finishedAt","parallelGroup","failed","startStep","step","workerGroup","completeStep","queueMs","durationMs","failStep","lockNow","lockedBy","lockedUntil","renew","setInterval","renewRunLock","floor","runRemoteExecution","runExecution","clearInterval","settleRun","outcome","wakeAt","admit","retryWakeAt","history","remoteHistory","decision","advance","err","RemoteWorkflowTimeout","String","stack","applyCommands","commands","checkpoints","kindOf","local","sleep","sort","cmd","attempt","ms","min","buffered","takeBufferedSignal","putSignalWaiter","compensations","snapshot","replay","ctx","createWorkflowCtx","ctxHostFor","ContinueAsNew","nextId","WorkflowSuspended","has","comp","runCompensation","callRemote","startChild","reply","continue","bp","find","breakpointToken","getEvent","getLatestCheckpointByName","registerUpdateValidator","validate","update","accepted","reason","existing","getCheckpoint","NonDeterminismError","callRemoteInMemory","maxAttempts","retries","retryable","backoffDelay","handles","tryAdmit","fairnessKey","waiterId","retryAt","validInput","parse","releaseQueueSlot","runIds","clear","release","resultPromise","resolution","awaitWithHeartbeat","RemoteStepTimeout","cleanup","arm","stepError","remoteStep","config","group","name","split","__remote","taskCounter","RemoteWorkflowExecutor","pending","Map","subscribed","transport","group","opts","ensureSubscribed","onDecision","Error","decision","resolve","get","taskId","delete","advance","run","history","dispatchWorkflowTask","id","task","runId","workflow","workflowVersion","input","priority","attempt","Promise","reject","set","timeoutMs","timer","setTimeout","RemoteWorkflowTimeout","unref","CodecStateStore","inner","codec","enc","v","undefined","encode","dec","decode","encRun","run","input","output","decRun","encCp","cp","decCp","ensureSchema","Promise","resolve","createRun","updateRun","runId","patch","next","getRun","deleteRun","getCheckpoint","seq","saveCheckpoint","checkpoint","transaction","work","Error","tx","raw","listIncompleteRuns","map","r","listPendingRuns","limit","listDueTimers","nowMs","tryLockRun","owner","leaseUntilMs","releaseRunLock","renewRunLock","putSignalWaiter","waiter","takeSignalWaiter","token","listSignalWaiters","prefix","bufferSignal","payload","takeBufferedSignal","buffered","listRuns","query","listCheckpoints","c","getLatestCheckpointByName","name","latest","listCheckpointsByNamePrefix","prefixes","matches","filter","some","p","startsWith","collectMetrics","engine","m","runs","started","completed","failed","suspended","steps","byWorkflow","stepDuration","sumMs","count","wf","name","k","entry","stop","subscribe","e","type","workflow","durationMs","snapshot","structuredClone","prometheus","lines","push","v","Object","entries","event","n","join","nodeRequire","createRequire","defaultSleep","ms","Promise","r","setTimeout","scheduledRunId","key","everyMs","nowMs","Math","floor","cronParser","loadCronParser","Error","prevCronFireMs","expr","timezone","parser","it","parseExpression","currentDate","Date","tz","prev","toDate","getTime","scheduleRunIdAt","s","cron","scheduleRunIdsAt","current","backfill","maxCatchup","ids","bucket","oldest","max","b","push","prior","cursor","i","before","reverse","runSchedules","engine","schedules","opts","random","sleep","paused","overlap","prevBucket","getRun","status","jitter","runId","start","workflow","input","compare","actual","op","expected","matchesAttributes","attributes","filters","length","every","f","key","value","applyAttributeQuery","rows","query","filtered","filter","r","searchAttributes","offset","limit","slice","normalizeAttributeRows","runId","out","Object","entries","push","strValue","numValue","sqlComparator","attributeColumnFor","attributeOperand","STATE_STORE","Symbol","for","TRANSPORT","DURABLE_OPTIONS","STATE_STORE_CANONICAL","TRANSPORT_CANONICAL","DURABLE_OPTIONS_CANONICAL","InMemoryStateStore","runs","Map","checkpoints","signalWaiters","attributeIndex","lastAttributeCandidates","lastCheckpointRowsRead","key","runId","seq","reindexAttributes","attributes","byRun","values","delete","row","normalizeAttributeRows","get","set","createRun","run","id","searchAttributes","updateRun","patch","existing","Error","next","getRun","deleteRun","cp","token","waiter","undefined","getCheckpoint","saveCheckpoint","checkpoint","listIncompleteRuns","filter","r","status","map","listPendingRuns","limit","sort","a","b","createdAt","getTime","localeCompare","slice","listDueTimers","nowMs","wakeAt","tryLockRun","owner","leaseUntilMs","lockedUntil","lockedBy","releaseRunLock","renewRunLock","putSignalWaiter","takeSignalWaiter","listSignalWaiters","prefix","w","startsWith","transaction","work","raw","bufferedSignals","bufferSignal","payload","queue","push","takeBufferedSignal","length","shift","candidatesForFilter","f","out","Set","numeric","value","operand","actual","numValue","strValue","ok","op","add","listRuns","query","workflow","statuses","includes","tag","tags","candidates","prev","has","size","ids","offset","listCheckpoints","rows","getLatestCheckpointByName","name","latest","listCheckpointsByNamePrefix","prefixes","some","p","InMemoryTransport","handlers","Map","resultHandler","stepEventHandler","controlHandlers","Set","handle","name","fn","set","dispatch","task","Error","result","runStepHandler","get","setImmediate","onResult","handler","onHeartbeat","_handler","dispatchStepEvent","event","onStepEvent","publishControl","msg","onControl","add"]}