@dudousxd/nestjs-durable-core 0.84.1 → 0.85.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1195,6 +1195,14 @@ interface StateStore {
1195
1195
  */
1196
1196
  updateRunIf?(runId: string, expectedStatuses: RunStatus[], patch: Partial<WorkflowRun>): Promise<boolean>;
1197
1197
  getRun(runId: string): Promise<WorkflowRun | null>;
1198
+ /**
1199
+ * The runs with these ids, in any order; an id with no run is left out. One `IN (...)` read: the
1200
+ * engine looks up a fan's children with it (which to start, which already finished) instead of
1201
+ * one {@link getRun} per child. Callers pass ids in bounded batches.
1202
+ *
1203
+ * Optional: without it the engine reads each run with {@link getRun}.
1204
+ */
1205
+ getRuns?(runIds: string[]): Promise<WorkflowRun[]>;
1198
1206
  /**
1199
1207
  * Hard-delete a run and all of its rows — the run plus its checkpoints, signal waiters, and
1200
1208
  * normalized search-attribute rows. Unlike a cancelled run (which stays as terminal history), a
@@ -2262,6 +2270,43 @@ interface NamedTransport {
2262
2270
  interface RunDispatcher {
2263
2271
  dispatch(runId: string): void | Promise<void>;
2264
2272
  }
2273
+ /**
2274
+ * One run handed to a transport's run queue ({@link Transport.dispatchRuns}), for whichever driving
2275
+ * instance takes it.
2276
+ *
2277
+ * - `start` (the default): a freshly created or re-queued `pending` run. The consumer runs it only
2278
+ * while it is still `pending`; any other state means another instance already took it.
2279
+ * - `wake`: a suspended run with something new to see (a delivered signal or child completion, a
2280
+ * due timer, a freed singleton or queue slot, a lease that came free). The consumer leases and
2281
+ * resumes it unless it is finished.
2282
+ */
2283
+ interface RunDispatch {
2284
+ runId: string;
2285
+ /** The run's admission priority (higher = more urgent), for a queue that orders by priority. */
2286
+ priority?: number | undefined;
2287
+ reason?: 'start' | 'wake' | undefined;
2288
+ /**
2289
+ * Which `pending` state of the run a `start` is for: the same for every dispatch of one pending
2290
+ * state (a start re-sent by the poll), different once the run went `pending` again (a retry, a
2291
+ * recovery). A transport that deduplicates may drop a start whose `runId` and `key` match one it
2292
+ * still holds; it must not drop one with a new key, even while the earlier one is being handled,
2293
+ * nor a wake. Absent on a wake.
2294
+ */
2295
+ key?: string | undefined;
2296
+ }
2297
+ /**
2298
+ * Which run queue {@link Transport.dispatchRuns} and {@link Transport.onDispatchedRun} use. Runs are
2299
+ * queued per engine `namespace` (undefined for an engine that drives every namespace), so engines
2300
+ * scoped to different namespaces on one broker never execute each other's runs.
2301
+ */
2302
+ interface RunQueueOptions {
2303
+ namespace?: string | undefined;
2304
+ }
2305
+ /** Options for {@link Transport.onDispatchedRun}. */
2306
+ interface RunConsumerOptions extends RunQueueOptions {
2307
+ /** Most runs this consumer hands to its handler at once. */
2308
+ concurrency: number;
2309
+ }
2265
2310
  interface Transport {
2266
2311
  /** engine → worker */
2267
2312
  dispatch(task: RemoteTask): Promise<void>;
@@ -2348,6 +2393,21 @@ interface Transport {
2348
2393
  dispatchRunRequest?(msg: RunRequest): Promise<void>;
2349
2394
  /** control plane ← tenant worker: consume {@link RunRequest}s. Pair with {@link dispatchRunRequest}. */
2350
2395
  onRunRequest?(handler: (msg: RunRequest) => Promise<void>): void;
2396
+ /**
2397
+ * engine → engine: queue `pending` runs for whichever driving instance takes them first, one entry
2398
+ * per run id (a run already queued is not queued twice). The engine sends a wide fan's children in
2399
+ * batches. Optional, together with {@link onDispatchedRun}: an engine that consumes the run queue
2400
+ * dispatches the runs it starts here instead of executing them in-process. A rejection leaves the
2401
+ * runs `pending` in the store for a `runPending` poll.
2402
+ */
2403
+ dispatchRuns?(runs: readonly RunDispatch[], opts?: RunQueueOptions): Promise<void>;
2404
+ /**
2405
+ * engine ← engine: consume the run queue, at most `opts.concurrency` runs at once on this
2406
+ * instance, handing each {@link RunDispatch} to `handler` as dispatched (its `reason` included);
2407
+ * `handler` resolves when its turn of the run settles. Returns a stop function that stops
2408
+ * taking runs and resolves once the runs in flight have settled. Pair with {@link dispatchRuns}.
2409
+ */
2410
+ onDispatchedRun?(handler: (run: RunDispatch) => Promise<void>, opts: RunConsumerOptions): () => Promise<void>;
2351
2411
  /** control plane → tenant worker: publish a correlated {@link RunReply} on `<effectivePrefix>-run-reply`
2352
2412
  * (pub/sub; every tenant subscribes and filters by `requestId`). */
2353
2413
  publishRunReply?(reply: RunReply): Promise<void>;
@@ -4442,8 +4502,10 @@ interface WorkflowEngineDeps {
4442
4502
  */
4443
4503
  trackStepStart?: boolean | undefined;
4444
4504
  /**
4445
- * Where a freshly-`start`ed run executes (see {@link RunDispatcher}). Defaults to in-process: the
4446
- * run executes on this instance asynchronously (a microtask), so `start` returns without blocking.
4505
+ * Where a freshly-`start`ed run executes (see {@link RunDispatcher}). By default the run executes
4506
+ * on this instance asynchronously, so `start` returns without blocking; once the engine consumes a
4507
+ * transport's run queue ({@link WorkflowEngine.consumeRuns}) it queues the run there instead, for
4508
+ * whichever driving instance takes it.
4447
4509
  * Pass a no-op dispatcher on a caller that must NOT run workflows (e.g. an API/dashboard pod), and
4448
4510
  * run `runPending` on a worker pod to pick those up; or a broker-backed one for a worker pool.
4449
4511
  */
@@ -4582,6 +4644,35 @@ declare class WorkflowEngine {
4582
4644
  private readonly stepQueue;
4583
4645
  /** Executions currently in flight, so a graceful shutdown can wait for them to settle. */
4584
4646
  private readonly inflight;
4647
+ /**
4648
+ * Work a settled turn leaves running in the background (a parent notification, a post-release
4649
+ * re-drive), so a graceful shutdown waits for it too: dropping one on exit strands the run until
4650
+ * its reconcile timer.
4651
+ */
4652
+ private readonly background;
4653
+ /**
4654
+ * Runs with an implicit wake executing on this instance, and whether another wake arrived for the
4655
+ * run meanwhile (see {@link resumeImplicit}).
4656
+ */
4657
+ private readonly wakeTurns;
4658
+ /** Re-checks scheduled for runs whose wake found another instance's lease (see {@link execute}). */
4659
+ private readonly leaseRetries;
4660
+ /**
4661
+ * Every run turn and child start this instance takes on itself, under one budget of
4662
+ * {@link LOCAL_RUN_CONCURRENCY}: the runs it dispatches to itself, a fan's deferred child starts,
4663
+ * enqueued pickups and the runs it takes off the transport's run queue.
4664
+ */
4665
+ private readonly localWork;
4666
+ /** The dispatcher the caller supplied, if any; without one the engine picks (see {@link dispatchRun}). */
4667
+ private readonly customDispatcher;
4668
+ /** Runs on their way to the transport's run queue (see {@link consumeRuns}). */
4669
+ private readonly runBatcher;
4670
+ /** Set while this engine consumes a transport's run queue, and so dispatches its runs to it. */
4671
+ private dispatchesOverTransport;
4672
+ /** Stops for the run-queue consumers started by {@link consumeRuns}. */
4673
+ private runConsumerStops;
4674
+ /** The consumers being stopped, so {@link drain} waits for their runs in flight. */
4675
+ private runConsumersStopping;
4585
4676
  /**
4586
4677
  * The run lease of each execution in flight on THIS instance, by run id — renewed while it runs
4587
4678
  * and checked by every settle (the zombie fence, see {@link ExecutionLease}). Also what `drain()`
@@ -4612,10 +4703,72 @@ declare class WorkflowEngine {
4612
4703
  getEntityState<S = unknown>(name: string, key: string): Promise<S | undefined>;
4613
4704
  /**
4614
4705
  * Be notified when a run is enqueued on ANOTHER instance (via the control plane), so a worker can
4615
- * pick it up at once — e.g. `engine.onEnqueued((runId) => engine.runOne(runId))`. Returns an
4706
+ * pick it up at once — e.g. `engine.onEnqueued((runId) => engine.runEnqueued(runId))`. Returns an
4616
4707
  * unsubscribe function. Only wire this on instances that should execute runs (workers).
4617
4708
  */
4618
4709
  onEnqueued(listener: (runId: string) => void): () => void;
4710
+ /**
4711
+ * Pick up a run another instance announced as enqueued: run it here if it is still `pending`.
4712
+ * Bounded by {@link LOCAL_RUN_CONCURRENCY}, and a run another instance already took is skipped
4713
+ * after one read, instead of being leased and replayed here once more.
4714
+ */
4715
+ runEnqueued(runId: string): void;
4716
+ /**
4717
+ * Consume the run queue of every transport that carries one ({@link Transport.dispatchRuns} and
4718
+ * {@link Transport.onDispatchedRun}), and from then on dispatch the runs this engine starts there
4719
+ * rather than executing them in-process: a run, a `ctx.all` fan's children included, executes on
4720
+ * whichever consuming instance takes it, at most {@link LOCAL_RUN_CONCURRENCY} at once per
4721
+ * instance. Call it on every instance that drives runs; the Nest module does on a driving operator.
4722
+ *
4723
+ * Returns a function that stops consuming and resolves once the runs in flight settled, after
4724
+ * which runs are executed in-process again; {@link beginDrain} stops consuming too. Undefined
4725
+ * when no transport carries a run queue: runs keep executing in-process.
4726
+ */
4727
+ consumeRuns(): (() => Promise<void>) | undefined;
4728
+ /** Stop every run-queue consumer; resolves once their runs in flight settled. */
4729
+ private stopRunConsumers;
4730
+ /** Whether {@link dispatchRun} queues runs on the transport (see {@link consumeRuns}). */
4731
+ private get queuesRunsOverTransport();
4732
+ /**
4733
+ * Hand a `pending` run to whatever executes it: the caller's {@link WorkflowEngineDeps.runDispatcher};
4734
+ * else the transport's run queue while this engine consumes it, batched; else this instance,
4735
+ * bounded by {@link LOCAL_RUN_CONCURRENCY}. A run whose queueing fails stays `pending` for a
4736
+ * `runPending` poll.
4737
+ */
4738
+ private dispatchRun;
4739
+ /**
4740
+ * Wake a suspended run that has something new to see (a delivered signal or child completion, a
4741
+ * lease that came free, a freed slot): while this engine consumes the transport's run queue, on
4742
+ * whichever instance takes the wake (the result then only says it was handed over); otherwise
4743
+ * here, now.
4744
+ */
4745
+ private wake;
4746
+ /**
4747
+ * Take a turn of a run taken off the transport's run queue. A `start` runs only while the run is
4748
+ * still `pending` (or `cancelling`, a recovered cancel): any other state means another instance
4749
+ * already took it. A `wake` leases and resumes the run unless it is finished. The run lease admits
4750
+ * one executor either way. Never rejects.
4751
+ */
4752
+ private runFromQueue;
4753
+ /**
4754
+ * Hand due runs (timers, blocked runs due for a fleet re-check) to whichever instance takes them
4755
+ * off the run queue. Each is claimed first, under its lease, by pushing its `wakeAt` one lease
4756
+ * period out, so the next poll (here or elsewhere) does not queue it again while it waits; a wake
4757
+ * that is lost brings it back due after that period. False when the transport refused the wakes,
4758
+ * so the caller resumes them itself.
4759
+ */
4760
+ private handOffDue;
4761
+ /**
4762
+ * Queue `runs` on the transport for whichever consuming instance takes them, in batches. False
4763
+ * when the transport refused them, so the caller executes them itself instead.
4764
+ */
4765
+ private queueOnTransport;
4766
+ /**
4767
+ * Execute a run announced by another instance, if it is still `pending`: a
4768
+ * run another instance already took is skipped after one read instead of being leased and
4769
+ * replayed here once more. Never rejects.
4770
+ */
4771
+ private runIfPending;
4619
4772
  /** Fire cooperative-cancellation listeners for `runId` (a worker bridge aborts in-flight work). */
4620
4773
  private notifyCancelled;
4621
4774
  /**
@@ -4816,6 +4969,8 @@ declare class WorkflowEngine {
4816
4969
  * stale waiter or a late result left behind by a failed run silently re-executes its body.
4817
4970
  */
4818
4971
  private resumeImplicit;
4972
+ /** Keep `work` in {@link background} until it settles; its failure is swallowed. */
4973
+ private inBackground;
4819
4974
  /**
4820
4975
  * One execution of a run at a time in this process. A resume that lands while the run executes
4821
4976
  * here neither joins that execution (the double-run) nor no-ops against its held lease (a lost
@@ -5247,6 +5402,32 @@ declare class WorkflowEngine {
5247
5402
  * instance opened is skipped, for the reason {@link settledHere} gives.
5248
5403
  */
5249
5404
  private redriveSettledStepFans;
5405
+ /**
5406
+ * Deliver the outcome of every awaited child that already finished but whose completion never
5407
+ * reached this run, into `checkpoints` (this turn's snapshot) and the store.
5408
+ *
5409
+ * A child persists its terminal status first and tells its parent after ({@link notifyParent}). A
5410
+ * crash, a scale-down or a store error between the two leaves the parent's `running` placeholder
5411
+ * and `child:<id>` waiter behind for a child that is done, and nothing else would ever settle
5412
+ * them: the parent's reconcile wake replays straight back to the same wait. So each turn looks up
5413
+ * the children of its `running` placeholders (one batched read per 500) and settles the finished
5414
+ * ones exactly as the child's own notification would have: the `signal:child:<id>` checkpoint
5415
+ * with the child's completion, then the waiter removed. A notification arriving late writes the
5416
+ * same checkpoint and finds no waiter. Best effort: a store error leaves the rest to the next turn.
5417
+ */
5418
+ private deliverFinishedChildren;
5419
+ /**
5420
+ * {@link deliverFinishedChildren} for a remote workflow, whose awaited children (`startChild`
5421
+ * commands) leave a `child:<id>` waiter but no placeholder checkpoint: the run's own waiters say
5422
+ * which children it is waiting on. One indexed read per turn of a remote run.
5423
+ */
5424
+ private deliverFinishedChildWaiters;
5425
+ /**
5426
+ * Settle every child in `awaited` that has finished: its `signal:child:<id>` checkpoint with the
5427
+ * child's completion, then its waiter removed, exactly as the child's own notification does, and
5428
+ * the checkpoint put into `checkpoints`. Children are read in batches of 500.
5429
+ */
5430
+ private settleFinishedChildren;
5250
5431
  private redriveSettledChildren;
5251
5432
  /**
5252
5433
  * Deliver an external signal to the run waiting on `token`, resume it with `payload`, and return
@@ -5308,6 +5489,22 @@ declare class WorkflowEngine {
5308
5489
  * knowing about the child feature.
5309
5490
  */
5310
5491
  private notifyParent;
5492
+ /**
5493
+ * {@link signal} a child's completion to its parent, retrying a store error a few times. The child
5494
+ * is already persisted terminal, so a failure here would leave the parent waiting on a child that
5495
+ * finished; the parent's own turns reconcile that ({@link deliverFinishedChildren}), but only on
5496
+ * its next wake. A waiter already taken is delivered to directly on a retry, so the completion is
5497
+ * not buffered for a waiter that no longer exists.
5498
+ */
5499
+ private deliverToParent;
5500
+ /**
5501
+ * Whether the parent of the child behind `token` (`child:<id>`) already holds `completion` as that
5502
+ * child's settled `signal:child:<id>` checkpoint: its own turn settled the child from the child's
5503
+ * row, so this notification is a duplicate. A different completion (a fix-and-replay run's success
5504
+ * for a child the parent saw fail) is not, and is buffered for the parent's retry. Only for a child
5505
+ * whose id the engine minted (its parent is derivable from it).
5506
+ */
5507
+ private parentHoldsCompletion;
5311
5508
  /**
5312
5509
  * Deferred child start shared by the in-process ctx host and the remote `startChild` command.
5313
5510
  * Deferred (microtask) so a fast child can't reentrantly resume a still-suspending parent. A start
@@ -5507,6 +5704,20 @@ declare class WorkflowEngine {
5507
5704
  private markStarted;
5508
5705
  private singletonWaitResult;
5509
5706
  private execute;
5707
+ /**
5708
+ * A wake that found the run leased by another instance is dropped, and normally that is fine: the
5709
+ * holder's turn either sees what the wake wrote, or re-checks once it releases the lease
5710
+ * ({@link redriveSettledSteps}, {@link redriveSettledChildren}). Not if the holder goes down first
5711
+ * (a scale-down mid-turn, an OOM): its lease lapses with the run `suspended` on a step that has
5712
+ * finished, and nothing wakes it before its timer.
5713
+ *
5714
+ * So the dropped wake is kept here: once the lease is free (looked at every
5715
+ * {@link LEASE_RECHECK_MAX_MS} at most, for a bounded number of times), a run still `suspended` is
5716
+ * leased and resumed. A holder that already moved the run on makes this one spare replay that
5717
+ * re-parks. Best effort; the run's timer remains the fallback if this instance goes down too.
5718
+ */
5719
+ private recheckAfterLease;
5720
+ private retryDroppedWake;
5510
5721
  /**
5511
5722
  * Renew `runId`'s lease for as long as this execution holds it, and register it in
5512
5723
  * {@link executionLeases} so settles can check the zombie fence and `drain()` can release it.
@@ -5898,6 +6109,12 @@ declare class WorkflowEngine {
5898
6109
  * whose read or write failed resolves its error, and the transport redelivers just that one.
5899
6110
  */
5900
6111
  private completeRemoteResults;
6112
+ /**
6113
+ * The outcomes for a batch of redelivered results (their steps already settled): one of them
6114
+ * resumes the run if it is `suspended` and, for a step of a fan, the fan's barrier is open. A
6115
+ * resume of a run that had in fact moved on replays to its current wait and re-parks.
6116
+ */
6117
+ private resumeForRedelivered;
5901
6118
  /**
5902
6119
  * The join barrier of a step fan: a result for one of its steps resumes the parent only once no
5903
6120
  * step of the fan is still `pending` (a settled wave), or on a failure (failFast surfaces it, and a
@@ -6529,6 +6746,22 @@ declare function listSignalWaitersOfRuns(store: StateStore, runIds: readonly str
6529
6746
  /** Index signal waiters by `runId`, keeping the first seen per run (a run parks on one waiter at a
6530
6747
  * time in the sequential case; the earliest is the one it's blocked on). */
6531
6748
  declare function indexWaitersByRun(waiters: readonly SignalWaiter[]): Map<string, SignalWaiter>;
6749
+ /**
6750
+ * The runs with these ids that exist: through the store's {@link StateStore.getRuns} in bounded
6751
+ * batches, or, for a store without it, one {@link StateStore.getRun} per id, a few at a time.
6752
+ * Throws if any read failed; see {@link readRunsByIds} to keep what was read.
6753
+ */
6754
+ declare function getRunsByIds(store: StateStore, runIds: readonly string[]): Promise<Map<string, WorkflowRun>>;
6755
+ /**
6756
+ * {@link getRunsByIds}, keeping what could be read: `runs` holds the existing runs among the ids
6757
+ * that were read, `unread` the ids whose read failed (with the first `error`). A failed read costs
6758
+ * only its own ids: one failing {@link StateStore.getRun} does not discard the rest of its batch.
6759
+ */
6760
+ declare function readRunsByIds(store: StateStore, runIds: readonly string[]): Promise<{
6761
+ runs: Map<string, WorkflowRun>;
6762
+ unread: string[];
6763
+ error?: unknown;
6764
+ }>;
6532
6765
 
6533
6766
  /**
6534
6767
  * The parent of a child run whose id the engine minted: a `ctx.all` child
@@ -6629,6 +6862,8 @@ declare class CodecStateStore implements StateStore {
6629
6862
  readonly registerChildWaits?: (entries: ChildWait[]) => Promise<void>;
6630
6863
  /** The folded checkpoint carries the children's outputs, so it is encoded. */
6631
6864
  readonly compactCheckpoints?: (runId: string, fromSeq: number, toSeq: number, into: StepCheckpoint) => Promise<void>;
6865
+ /** Decodes each run like {@link getRun}. Bound only when the inner store has it. */
6866
+ readonly getRuns?: (runIds: string[]) => Promise<WorkflowRun[]>;
6632
6867
  /** Forwarded verbatim — a waiter carries no payload. */
6633
6868
  readonly listSignalWaitersByRun?: (runIds: string[]) => Promise<SignalWaiter[]>;
6634
6869
  /** Forwarded verbatim — a waiter carries no payload. */
@@ -6803,6 +7038,8 @@ interface ScheduledWorkflow<W extends WorkflowRef = WorkflowRef> {
6803
7038
  /**
6804
7039
  * Randomly delay the dispatch by up to this many ms BEFORE firing, to spread load when many
6805
7040
  * instances tick on the same boundary (avoids a thundering herd). Opt-in; absent = fire immediately.
7041
+ * The window is deferred to a later tick, never waited for inside one, so a jittered schedule does
7042
+ * not hold up any other schedule or the rest of the timer poll.
6806
7043
  *
6807
7044
  * This is dispatch-path jitter only — it does NOT affect the run id (still the time bucket), so
6808
7045
  * idempotency is unchanged: two instances jittering the same window still start it exactly once.
@@ -6831,9 +7068,13 @@ interface ScheduledWorkflow<W extends WorkflowRef = WorkflowRef> {
6831
7068
  namespace?: string;
6832
7069
  }
6833
7070
  /** Injectable dispatch-path effects (kept out of the deterministic run-id logic). Defaults to real
6834
- * `Math.random` + `setTimeout`; overridden in tests so jitter is deterministic and instant. */
7071
+ * `Math.random`; overridden in tests so jitter is deterministic. */
6835
7072
  interface RunSchedulesOptions {
6836
7073
  random?: () => number;
7074
+ /**
7075
+ * @deprecated No longer called: jitter defers a window to a later tick instead of sleeping inside
7076
+ * this one. Kept so existing callers still type-check.
7077
+ */
6837
7078
  sleep?: (ms: number) => Promise<void>;
6838
7079
  }
6839
7080
  /** Deterministic run id for a fixed-interval schedule's current time window. */
@@ -6863,8 +7104,8 @@ declare function scheduleRunIdAt(s: ScheduledWorkflow, nowMs: number): string;
6863
7104
  * racing two instances on the same tick — starts **each window exactly once**. Wire it to a
6864
7105
  * `setInterval`, the durable timer poller, or `@nestjs/schedule`. Returns the run ids this call
6865
7106
  * started: a window that already has a run is not started or returned again, and once this process
6866
- * has seen a window's run exist, later calls in that window skip it without a store read or a
6867
- * jitter sleep.
7107
+ * has seen a window's run exist, later calls in that window skip it without a store read. A
7108
+ * jittered window is deferred to a later call, never slept on.
6868
7109
  */
6869
7110
  declare function runSchedules(engine: Pick<WorkflowEngine, 'start' | 'getRun'> & Partial<Pick<WorkflowEngine, 'isDraining'>>, schedules: readonly ScheduledWorkflow[], nowMs: number, opts?: RunSchedulesOptions): Promise<string[]>;
6870
7111
 
@@ -7124,6 +7365,7 @@ declare class InMemoryStateStore implements StateStore {
7124
7365
  updateRunIf(runId: string, expectedStatuses: RunStatus[], patch: Partial<WorkflowRun>): Promise<boolean>;
7125
7366
  private applyRunPatch;
7126
7367
  getRun(runId: string): Promise<WorkflowRun | null>;
7368
+ getRuns(runIds: string[]): Promise<WorkflowRun[]>;
7127
7369
  deleteRun(runId: string): Promise<void>;
7128
7370
  deleteRuns(runIds: string[]): Promise<void>;
7129
7371
  pruneTerminalRuns(policy: RetentionPolicy, nowMs: number, limit: number): Promise<number>;
@@ -7229,6 +7471,25 @@ declare class InMemoryTransport implements Transport, ControlPlane {
7229
7471
  onControl(handler: (msg: ControlMessage) => void): void;
7230
7472
  }
7231
7473
 
7474
+ /**
7475
+ * An in-process run queue shared by several {@link Transport}s, for tests: each
7476
+ * {@link InMemoryRunQueue.transport} is one instance of a deployment, and a run queued by any of
7477
+ * them goes to whichever consumer has a free slot, round-robin. A run waiting in the queue is not
7478
+ * queued twice (a wake turns a waiting start into a wake); one being handled is queued again.
7479
+ * Higher priority goes first. The transports carry no remote steps.
7480
+ */
7481
+ declare class InMemoryRunQueue {
7482
+ private readonly lanes;
7483
+ /** A transport on this queue. */
7484
+ transport(): Transport;
7485
+ /** Runs waiting in the queue of `namespace`. */
7486
+ waiting(namespace?: string): string[];
7487
+ private lane;
7488
+ private add;
7489
+ private consume;
7490
+ private pump;
7491
+ }
7492
+
7232
7493
  /** Reserved engine metadata: a durable singleton slot, independent of the execution lease. */
7233
7494
  declare const SINGLETON_ADMITTED_TAG = "durable:singleton:admitted";
7234
7495
  /**
@@ -7279,4 +7540,4 @@ declare function singletonAdmissionDenialPatch(runs: WorkflowRun[], runId: strin
7279
7540
  updatedAt: Date;
7280
7541
  } | undefined;
7281
7542
 
7282
- export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AllOptions, type AllSettledOptions, type AllStepsOptions, type AllStepsSettledOptions, type AnnouncedWorkflow, type AnnouncementEvidence, type AttributeFilter, type AttributeOp, type AttributePredicateOperand, type AttributeValue, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CHILD_EDGE_PREFIXES, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type CheckpointAggregatingStore, type CheckpointNameKind, type CheckpointQuery, type CheckpointStat, type ChildCallOptions, type ChildWait, CodecStateStore, type CodecStateStoreOptions, type ConcurrencyConfig, ConcurrencyLimitError, type ConcurrencyQuota, ContinueAsNew, type ControlMessage, type ControlPlane, DEFAULT_CONCURRENCY_STATUSES, DEFAULT_PARTITION, DEFAULT_STALLED_AFTER_MS, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type Disagreement, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, type DynamicWorkflowCtx, ENGINE_MINTED_TAG_PREFIXES, ENTITY_WORKFLOW, EVENT_BUFFER_SCAN_LIMIT, EVENT_TOKEN_PREFIX, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, type EntityWorkflowHost, EventAccumulators, type EventBatchConfig, FAN_SUMMARY_FAILURES, type FanJoin, type FanPage, type FanPageQuery, type FanSummary, type FanWait, FatalError, type FindStalledRunsOptions, GatherError, type GatherItemFailure, type GroupHealth, HANDOFF_SEQ_BASE, type Heartbeat, type HeartbeatSighting, type HeartbeatStatus, type HistoryEvent, InMemoryAdmissionBackend, InMemoryStateStore, InMemoryTransport, type InferSearchAttributes, LEGACY_V1_CAPABILITIES, LEGACY_V1_PROTOCOL, type ListStalledRunsOptions, type MetricsCollector, type MetricsSnapshot, type NamedTransport, type NegotiateOptions, type NegotiationOutcome, type NegotiationReason, type NegotiationResult, NestedWorkflowCallError, NonDeterminismError, type OnErrorInput, type OnErrorRoute, type OwnedLeaseReclaim, type PartitionSighting, type PayloadCodec, type QueueConfig, QueueController, RUN_HISTORY_FIXTURE_VERSION, RUN_VALUE_FACET_LIMIT, RUN_VALUE_FACET_SCAN, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDetailOptions, type RunDispatcher, type RunFacetQuery, type RunFacetRow, RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunScope, type RunStatus, type RunValueAxis, type RunValueFacetOptions, type RunValueFacetOrder, type RunValueFacetRow, type RunWaiting, SINGLETON_ACTIVE_STATUSES, SINGLETON_ADMITTED_TAG, SINGLETON_RESERVED_TAGS, SINGLETON_TRACKED_TAG, STATE_STORE, STATE_STORE_CANONICAL, SUMMARY_CHILD_LIMIT, type ScalarAttributeFilter, ScheduleAlreadyExistsError, ScheduleClient, type ScheduleClientOptions, type ScheduleDescription, type ScheduleHost, type ScheduleListQuery, ScheduleNotFoundError, type ScheduleOptions, type ScheduleQuery, type ScheduleRecord, type ScheduledWorkflow, type SchemaIssue, type SchemaValidationCode, SchemaValidationError, type SearchAttributes, type SearchAttributesSchema, type Settled, SignalTimeoutError, type SignalWaiter, type SingletonConfig, SingletonQueueFullError, type StalePendingStep, type StalledRunInfo, StandardSchemaV1, type StartOptions, type StartRunMessage, type StateStore, type StepCheckpoint, type StepConfig, type StepDef, type StepDispatchOpts, type StepError, type StepEvent, type StepHandler, type StepInterceptor, type StepInvocation, type StepKind, type StepLogger, type StepOptions, type StepRef, type StepResult, type StepScope, type StepUndo, type StoreTransaction, type SubProcessHandle, TERMINAL_RUN_STATUSES, TRANSPORT, TRANSPORT_CANONICAL, type TenantEvent, type TenantTokenSource, type TenantVerifier, type Transport, type UndoOf, type UpdateResult, type UpdateValidator, VERSION_UNDECLARED_TAG, type VerifiedTenant, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, type WorkflowAnnouncement, WorkflowBlocked, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, type WorkflowDirectory, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRegistration, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, aggregateAnnouncements, aggregatesCheckpoints, announcementsOf, applyAttributeQuery, assertConcurrency, assertRoutes, attributeColumnFor, attributeOperand, attributePredicateOperands, axisIsRunColumn, bindWorkflowClass, breakpointToken, buildWorkflowDirectory, canRoute, capableWorkers, checkpointNameKind, checkpointStatsOf, childIdsOf, classifyWaiterToken, clearDurableExecutionWrappers, clearTerminalSingletonAdmission, codeAndDetails, codeOf, collectMetrics, concurrencyTag, controlPlaneDescriptor, countRuns, coveredTokens, createStepLogger, currentStep, currentStepScope, currentWorkflowCtx, debug, describeWorker, descriptorHash, detailsOf, error, etagMatches, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, facetOrigin, fanPageBounds, fanPageEtag, findStalledRuns, foldedCount, handoffHandlerId, handoffName, hasDurableExecutionWrappers, heartbeatStatus, hmacTenantVerifier, indexWaitersByRun, info, isEngineMintedTag, isEventToken, isFailedMember, isLegacyDescriptor, isNonEmptyRunScope, isWorkflowControlFlowSignal, legacySingletonHolders, listSignalWaitersOfRuns, liveHandoff, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, nextCronFireMs, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, onErrorRunId, pageFan, pageFanFromStore, parentRunIdOf, parseDuration, parseWebhookToken, partitionOfToken, planDispatch, poolNamespace, prevCronFireMs, queryCheckpointsOf, readSearchAttributes, requiredCapabilities, resolveConcurrency, resolveRouting, resolveRunWaiting, resolveTenantToken, resolveWireTenant, retiredHandoffName, routeFor, runDetailEtag, runDurableExecution, runInStepLogger, runInStepScope, runInWorkflowCtx, runOutsideWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduleRunIdAt, scheduledRunId, signTenantToken, singletonAdmissionDenialPatch, singletonAdmissionTags, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, summarizeFan, summarizeRunFromStore, summarizeTimeline, tenantGroup, useDurableExecution, warn, withSingletonTracked, withoutSingletonMarkers, workflowName };
7543
+ export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AllOptions, type AllSettledOptions, type AllStepsOptions, type AllStepsSettledOptions, type AnnouncedWorkflow, type AnnouncementEvidence, type AttributeFilter, type AttributeOp, type AttributePredicateOperand, type AttributeValue, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CHILD_EDGE_PREFIXES, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type CheckpointAggregatingStore, type CheckpointNameKind, type CheckpointQuery, type CheckpointStat, type ChildCallOptions, type ChildWait, CodecStateStore, type CodecStateStoreOptions, type ConcurrencyConfig, ConcurrencyLimitError, type ConcurrencyQuota, ContinueAsNew, type ControlMessage, type ControlPlane, DEFAULT_CONCURRENCY_STATUSES, DEFAULT_PARTITION, DEFAULT_STALLED_AFTER_MS, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type Disagreement, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, type DynamicWorkflowCtx, ENGINE_MINTED_TAG_PREFIXES, ENTITY_WORKFLOW, EVENT_BUFFER_SCAN_LIMIT, EVENT_TOKEN_PREFIX, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, type EntityWorkflowHost, EventAccumulators, type EventBatchConfig, FAN_SUMMARY_FAILURES, type FanJoin, type FanPage, type FanPageQuery, type FanSummary, type FanWait, FatalError, type FindStalledRunsOptions, GatherError, type GatherItemFailure, type GroupHealth, HANDOFF_SEQ_BASE, type Heartbeat, type HeartbeatSighting, type HeartbeatStatus, type HistoryEvent, InMemoryAdmissionBackend, InMemoryRunQueue, InMemoryStateStore, InMemoryTransport, type InferSearchAttributes, LEGACY_V1_CAPABILITIES, LEGACY_V1_PROTOCOL, type ListStalledRunsOptions, type MetricsCollector, type MetricsSnapshot, type NamedTransport, type NegotiateOptions, type NegotiationOutcome, type NegotiationReason, type NegotiationResult, NestedWorkflowCallError, NonDeterminismError, type OnErrorInput, type OnErrorRoute, type OwnedLeaseReclaim, type PartitionSighting, type PayloadCodec, type QueueConfig, QueueController, RUN_HISTORY_FIXTURE_VERSION, RUN_VALUE_FACET_LIMIT, RUN_VALUE_FACET_SCAN, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunConsumerOptions, type RunDetail, type RunDetailOptions, type RunDispatch, type RunDispatcher, type RunFacetQuery, type RunFacetRow, RunGateway, type RunListItem, type RunQuery, type RunQueueOptions, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunScope, type RunStatus, type RunValueAxis, type RunValueFacetOptions, type RunValueFacetOrder, type RunValueFacetRow, type RunWaiting, SINGLETON_ACTIVE_STATUSES, SINGLETON_ADMITTED_TAG, SINGLETON_RESERVED_TAGS, SINGLETON_TRACKED_TAG, STATE_STORE, STATE_STORE_CANONICAL, SUMMARY_CHILD_LIMIT, type ScalarAttributeFilter, ScheduleAlreadyExistsError, ScheduleClient, type ScheduleClientOptions, type ScheduleDescription, type ScheduleHost, type ScheduleListQuery, ScheduleNotFoundError, type ScheduleOptions, type ScheduleQuery, type ScheduleRecord, type ScheduledWorkflow, type SchemaIssue, type SchemaValidationCode, SchemaValidationError, type SearchAttributes, type SearchAttributesSchema, type Settled, SignalTimeoutError, type SignalWaiter, type SingletonConfig, SingletonQueueFullError, type StalePendingStep, type StalledRunInfo, StandardSchemaV1, type StartOptions, type StartRunMessage, type StateStore, type StepCheckpoint, type StepConfig, type StepDef, type StepDispatchOpts, type StepError, type StepEvent, type StepHandler, type StepInterceptor, type StepInvocation, type StepKind, type StepLogger, type StepOptions, type StepRef, type StepResult, type StepScope, type StepUndo, type StoreTransaction, type SubProcessHandle, TERMINAL_RUN_STATUSES, TRANSPORT, TRANSPORT_CANONICAL, type TenantEvent, type TenantTokenSource, type TenantVerifier, type Transport, type UndoOf, type UpdateResult, type UpdateValidator, VERSION_UNDECLARED_TAG, type VerifiedTenant, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, type WorkflowAnnouncement, WorkflowBlocked, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, type WorkflowDirectory, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRegistration, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, aggregateAnnouncements, aggregatesCheckpoints, announcementsOf, applyAttributeQuery, assertConcurrency, assertRoutes, attributeColumnFor, attributeOperand, attributePredicateOperands, axisIsRunColumn, bindWorkflowClass, breakpointToken, buildWorkflowDirectory, canRoute, capableWorkers, checkpointNameKind, checkpointStatsOf, childIdsOf, classifyWaiterToken, clearDurableExecutionWrappers, clearTerminalSingletonAdmission, codeAndDetails, codeOf, collectMetrics, concurrencyTag, controlPlaneDescriptor, countRuns, coveredTokens, createStepLogger, currentStep, currentStepScope, currentWorkflowCtx, debug, describeWorker, descriptorHash, detailsOf, error, etagMatches, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, facetOrigin, fanPageBounds, fanPageEtag, findStalledRuns, foldedCount, getRunsByIds, handoffHandlerId, handoffName, hasDurableExecutionWrappers, heartbeatStatus, hmacTenantVerifier, indexWaitersByRun, info, isEngineMintedTag, isEventToken, isFailedMember, isLegacyDescriptor, isNonEmptyRunScope, isWorkflowControlFlowSignal, legacySingletonHolders, listSignalWaitersOfRuns, liveHandoff, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, nextCronFireMs, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, onErrorRunId, pageFan, pageFanFromStore, parentRunIdOf, parseDuration, parseWebhookToken, partitionOfToken, planDispatch, poolNamespace, prevCronFireMs, queryCheckpointsOf, readRunsByIds, readSearchAttributes, requiredCapabilities, resolveConcurrency, resolveRouting, resolveRunWaiting, resolveTenantToken, resolveWireTenant, retiredHandoffName, routeFor, runDetailEtag, runDurableExecution, runInStepLogger, runInStepScope, runInWorkflowCtx, runOutsideWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduleRunIdAt, scheduledRunId, signTenantToken, singletonAdmissionDenialPatch, singletonAdmissionTags, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, summarizeFan, summarizeRunFromStore, summarizeTimeline, tenantGroup, useDurableExecution, warn, withSingletonTracked, withoutSingletonMarkers, workflowName };