@dudousxd/nestjs-durable-core 0.4.0 → 0.6.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.
Files changed (47) hide show
  1. package/dist/backoff.d.ts +5 -0
  2. package/dist/backoff.d.ts.map +1 -0
  3. package/dist/backoff.js +14 -0
  4. package/dist/backoff.js.map +1 -0
  5. package/dist/checkpoints.d.ts +17 -0
  6. package/dist/checkpoints.d.ts.map +1 -0
  7. package/dist/checkpoints.js +28 -0
  8. package/dist/checkpoints.js.map +1 -0
  9. package/dist/completion.d.ts +15 -0
  10. package/dist/completion.d.ts.map +1 -0
  11. package/dist/completion.js +13 -0
  12. package/dist/completion.js.map +1 -0
  13. package/dist/engine.d.ts +121 -10
  14. package/dist/engine.d.ts.map +1 -1
  15. package/dist/engine.js +318 -272
  16. package/dist/engine.js.map +1 -1
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/interfaces.d.ts +122 -3
  22. package/dist/interfaces.d.ts.map +1 -1
  23. package/dist/protocol.d.ts +3 -0
  24. package/dist/protocol.d.ts.map +1 -1
  25. package/dist/protocol.js +13 -1
  26. package/dist/protocol.js.map +1 -1
  27. package/dist/queue.d.ts +48 -0
  28. package/dist/queue.d.ts.map +1 -0
  29. package/dist/queue.js +45 -0
  30. package/dist/queue.js.map +1 -0
  31. package/dist/scheduler.d.ts +22 -7
  32. package/dist/scheduler.d.ts.map +1 -1
  33. package/dist/scheduler.js +40 -6
  34. package/dist/scheduler.js.map +1 -1
  35. package/dist/testing/in-memory-transport.d.ts +9 -4
  36. package/dist/testing/in-memory-transport.d.ts.map +1 -1
  37. package/dist/testing/in-memory-transport.js +14 -2
  38. package/dist/testing/in-memory-transport.js.map +1 -1
  39. package/dist/transport-pool.d.ts +23 -0
  40. package/dist/transport-pool.d.ts.map +1 -0
  41. package/dist/transport-pool.js +54 -0
  42. package/dist/transport-pool.js.map +1 -0
  43. package/dist/workflow-ctx.d.ts +46 -0
  44. package/dist/workflow-ctx.d.ts.map +1 -0
  45. package/dist/workflow-ctx.js +260 -0
  46. package/dist/workflow-ctx.js.map +1 -0
  47. package/package.json +8 -1
@@ -0,0 +1,5 @@
1
+ import type { StepOptions } from './interfaces';
2
+ /** Delay in ms before the next retry attempt, per a step's `StepOptions` backoff config. Shared by
3
+ * the local-step retry loop and the durable remote-step retry, so they stay consistent. */
4
+ export declare function backoffDelay(attempt: number, options?: StepOptions): number;
5
+ //# sourceMappingURL=backoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backoff.d.ts","sourceRoot":"","sources":["../src/backoff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;4FAC4F;AAC5F,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,CAM3E"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.backoffDelay = backoffDelay;
4
+ /** Delay in ms before the next retry attempt, per a step's `StepOptions` backoff config. Shared by
5
+ * the local-step retry loop and the durable remote-step retry, so they stay consistent. */
6
+ function backoffDelay(attempt, options) {
7
+ const base = options?.backoffMs ?? 0;
8
+ if (base <= 0)
9
+ return 0;
10
+ const raw = options?.backoff === 'exp' ? base * 2 ** (attempt - 1) : base;
11
+ const capped = options?.backoffMaxMs ? Math.min(raw, options.backoffMaxMs) : raw;
12
+ return options?.jitter ? Math.round(capped * (0.5 + Math.random() * 0.5)) : capped;
13
+ }
14
+ //# sourceMappingURL=backoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backoff.js","sourceRoot":"","sources":["../src/backoff.ts"],"names":[],"mappings":";;AAIA,oCAMC;AARD;4FAC4F;AAC5F,SAAgB,YAAY,CAAC,OAAe,EAAE,OAAqB;IACjE,MAAM,IAAI,GAAG,OAAO,EAAE,SAAS,IAAI,CAAC,CAAC;IACrC,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,OAAO,EAAE,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,MAAM,MAAM,GAAG,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACjF,OAAO,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACrF,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { StepCheckpoint, StepKind } from './interfaces';
2
+ /**
3
+ * Build an *instantaneous* checkpoint — one with no distinct enqueue/run/finish phases (a durable
4
+ * sleep timer, a breakpoint marker, a delivered signal, a published `setEvent` value, a `patched`
5
+ * marker). All three timestamps collapse to now and `attempts` is 1. Collapses what was five
6
+ * near-identical 10-field `saveCheckpoint({...})` literals into one builder.
7
+ */
8
+ export declare function instantCheckpoint(p: {
9
+ runId: string;
10
+ seq: number;
11
+ name: string;
12
+ kind: StepKind;
13
+ status?: StepCheckpoint['status'];
14
+ output?: unknown;
15
+ wakeAt?: number;
16
+ }): StepCheckpoint;
17
+ //# sourceMappingURL=checkpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoints.d.ts","sourceRoot":"","sources":["../src/checkpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,cAAc,CAgBjB"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.instantCheckpoint = instantCheckpoint;
4
+ const protocol_1 = require("./protocol");
5
+ /**
6
+ * Build an *instantaneous* checkpoint — one with no distinct enqueue/run/finish phases (a durable
7
+ * sleep timer, a breakpoint marker, a delivered signal, a published `setEvent` value, a `patched`
8
+ * marker). All three timestamps collapse to now and `attempts` is 1. Collapses what was five
9
+ * near-identical 10-field `saveCheckpoint({...})` literals into one builder.
10
+ */
11
+ function instantCheckpoint(p) {
12
+ const at = new Date();
13
+ return {
14
+ runId: p.runId,
15
+ seq: p.seq,
16
+ name: p.name,
17
+ kind: p.kind,
18
+ stepId: (0, protocol_1.stepId)(p.runId, p.seq),
19
+ status: p.status ?? 'completed',
20
+ output: p.output,
21
+ wakeAt: p.wakeAt,
22
+ attempts: 1,
23
+ enqueuedAt: at,
24
+ startedAt: at,
25
+ finishedAt: at,
26
+ };
27
+ }
28
+ //# sourceMappingURL=checkpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoints.js","sourceRoot":"","sources":["../src/checkpoints.ts"],"names":[],"mappings":";;AASA,8CAwBC;AAhCD,yCAAoC;AAEpC;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,CAQjC;IACC,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC;IACtB,OAAO;QACL,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,MAAM,EAAE,IAAA,iBAAM,EAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC;QAC9B,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,WAAW;QAC/B,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,EAAE;QACd,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,EAAE;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The payload an external `ctx.task` / child run delivers back on its completion signal: either a
3
+ * value or a failure. One typed envelope so `task` and `child` share the same unwrap (instead of
4
+ * sniffing ad-hoc `__error` keys).
5
+ */
6
+ export type Completion<T> = {
7
+ ok: true;
8
+ value: T;
9
+ } | {
10
+ ok: false;
11
+ error: string;
12
+ };
13
+ /** Read a `Completion` from a signal payload: return the value, or throw a FatalError if it failed. */
14
+ export declare function unwrapCompletion<T>(payload: unknown, label: string): T;
15
+ //# sourceMappingURL=completion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAElF,uGAAuG;AACvG,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAMtE"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unwrapCompletion = unwrapCompletion;
4
+ const errors_1 = require("./errors");
5
+ /** Read a `Completion` from a signal payload: return the value, or throw a FatalError if it failed. */
6
+ function unwrapCompletion(payload, label) {
7
+ const c = payload;
8
+ if (c && typeof c === 'object' && 'ok' in c && c.ok === false) {
9
+ throw new errors_1.FatalError(`${label} failed: ${c.error}`);
10
+ }
11
+ return c?.value;
12
+ }
13
+ //# sourceMappingURL=completion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.js","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":";;AAUA,4CAMC;AAhBD,qCAAsC;AAStC,uGAAuG;AACvG,SAAgB,gBAAgB,CAAI,OAAgB,EAAE,KAAa;IACjE,MAAM,CAAC,GAAG,OAA+B,CAAC;IAC1C,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC9D,MAAM,IAAI,mBAAU,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAQ,CAAyB,EAAE,KAAU,CAAC;AAChD,CAAC"}
package/dist/engine.d.ts CHANGED
@@ -1,14 +1,51 @@
1
- import type { EngineListener, RunResult, StateStore, StepError, Transport, WorkflowCtx } from './interfaces';
1
+ import type { ControlPlane, EngineListener, NamedTransport, RunResult, StateStore, StepError, Transport, UpdateResult, UpdateValidator, WorkflowCtx } from './interfaces';
2
+ import { type QueueConfig } from './queue';
2
3
  type WorkflowFn = (ctx: WorkflowCtx, input: unknown) => Promise<unknown>;
3
4
  export interface WorkflowEngineDeps {
4
5
  store: StateStore;
6
+ /** A single task transport. Shorthand for a one-entry `transports` pool (id `default`). */
5
7
  transport?: Transport;
8
+ /**
9
+ * An ordered pool of named transports. The engine dispatches on the first and fails over to the
10
+ * next on a dispatch error; a step pins one via `ctx.call(step, input, { transport: id })`. Use
11
+ * this instead of `transport` for failover / multi-broker setups.
12
+ */
13
+ transports?: NamedTransport[];
14
+ /**
15
+ * Cross-instance broadcast pub/sub for lifecycle events + cancellation (see {@link ControlPlane}).
16
+ * Separate from the task `transport`; omit for a single-instance / local-only setup. A transport
17
+ * that can also broadcast may be passed here as well.
18
+ */
19
+ controlPlane?: ControlPlane;
6
20
  /** Epoch-ms clock; injectable for tests. Defaults to `Date.now`. */
7
21
  clock?: () => number;
8
22
  /** Unique id for this engine instance, used for recovery leases. Defaults to a random id. */
9
23
  instanceId?: string;
10
24
  /** Recovery lease duration in ms — how long this instance owns a run it picked up. Default 30s. */
11
25
  leaseMs?: number;
26
+ /**
27
+ * Cap how many times crash-recovery may pick up the same still-`running` run before giving up and
28
+ * moving it to the `dead` dead-letter state (a poison pill that crashes the process every boot).
29
+ * Omit for unlimited (the default — recovery always retries).
30
+ */
31
+ maxRecoveryAttempts?: number;
32
+ /**
33
+ * Build the public callback URL for a `ctx.webhook()` token (e.g.
34
+ * ``(t) => `https://api.example.com/durable/webhooks/${t}` ``). Populates
35
+ * {@link DurableWebhook.url}. Omit if you build URLs yourself from the token.
36
+ */
37
+ webhookUrl?: (token: string) => string;
38
+ /**
39
+ * Provide the current W3C `traceparent` to stamp on each dispatched {@link RemoteTask}, so a
40
+ * worker (including the Python SDK) continues the distributed trace. Keep core OTel-free: supply
41
+ * `otelTraceparent` from `@dudousxd/nestjs-durable-otel`, or your own context reader. Omit to send none.
42
+ */
43
+ traceparent?: () => string | undefined;
44
+ /**
45
+ * Attempts for each saga compensation when the run fails (a transient undo — e.g. a refund API
46
+ * hiccup — gets another try). Default 1 (no retry). Compensations must be idempotent.
47
+ */
48
+ compensationRetries?: number;
12
49
  }
13
50
  /**
14
51
  * The orchestrator. Owns workflow state and replays runs deterministically: each step's
@@ -18,10 +55,16 @@ export interface WorkflowEngineDeps {
18
55
  */
19
56
  export declare class WorkflowEngine {
20
57
  private readonly store;
21
- private readonly transport?;
58
+ /** Ordered transport pool (dispatch + failover). Empty = no remote steps. */
59
+ private readonly pool;
60
+ private readonly controlPlane?;
22
61
  private readonly clock;
23
62
  private readonly instanceId;
24
63
  private readonly leaseMs;
64
+ private readonly maxRecoveryAttempts?;
65
+ private readonly webhookUrl?;
66
+ private readonly traceparent?;
67
+ private readonly compensationRetries;
25
68
  /** Every registered workflow, keyed by `name@version` — so old versions stay runnable. */
26
69
  private readonly workflows;
27
70
  /** The newest registered version per workflow name — used to `start` new runs. */
@@ -31,19 +74,48 @@ export declare class WorkflowEngine {
31
74
  /** Per-step "reset the liveness timer" callbacks, called when a heartbeat arrives. */
32
75
  private readonly heartbeatResets;
33
76
  private readonly listeners;
77
+ /** Callbacks notified (on any instance) when a run is cancelled — for cooperative cancellation. */
78
+ private readonly cancelListeners;
79
+ /** Validators gating `engine.update`, keyed by `<workflow>:<updateName>`. */
80
+ private readonly updateValidators;
81
+ /** Runs being cancelled WITH saga compensation — see `cancel({ compensate: true })`. */
82
+ private readonly cancelRequested;
83
+ /** Flow-control queues for remote steps, keyed by name (see {@link registerQueue}). */
84
+ private readonly queues;
85
+ /** Which queue a dispatched step took a slot from, by stepId — so the result can release it. */
86
+ private readonly stepQueue;
34
87
  /** Executions currently in flight, so a graceful shutdown can wait for them to settle. */
35
88
  private readonly inflight;
36
89
  private draining;
37
90
  constructor(deps: WorkflowEngineDeps);
91
+ /** Fire cooperative-cancellation listeners for `runId` (a worker bridge aborts in-flight work). */
92
+ private notifyCancelled;
38
93
  /**
39
94
  * Register a workflow version. Register multiple versions of the same name to keep in-flight
40
95
  * runs working across a breaking change: old runs resume on the version they started on, new
41
96
  * runs start on the newest registered version.
42
97
  */
43
98
  register(name: string, version: string, fn: WorkflowFn): void;
99
+ /**
100
+ * Register a flow-control queue referenced by `ctx.call(step, input, { queue })`. Caps concurrent
101
+ * in-flight steps and/or the admission rate; blocked calls re-suspend and retry, so the limit is
102
+ * durable. Per engine instance (see {@link QueueConfig}). Registering the same name replaces it.
103
+ */
104
+ registerQueue(config: QueueConfig): void;
44
105
  /** Subscribe to lifecycle events. Returns an unsubscribe function. */
45
106
  subscribe(listener: EngineListener): () => void;
107
+ /**
108
+ * Be notified when a run is cancelled — on ANY instance, via the transport control plane. A
109
+ * worker bridge can use this for cooperative cancellation: abort the in-flight work for `runId`
110
+ * instead of finishing it just to have the result discarded. Returns an unsubscribe function.
111
+ */
112
+ onCancel(listener: (runId: string) => void): () => void;
113
+ /** Emit a locally-produced lifecycle event: deliver to subscribers AND broadcast it on the
114
+ * control plane so other instances (e.g. a dashboard pod) can live-tail this run. */
46
115
  private emit;
116
+ /** Deliver an event to local subscribers only (no re-broadcast) — used for both locally-produced
117
+ * events and ones received from the control plane, so an event shows up once on every instance. */
118
+ private deliver;
47
119
  start(workflow: string, input: unknown, runId: string): Promise<RunResult>;
48
120
  resume(runId: string): Promise<RunResult>;
49
121
  /** Track an in-flight execution so {@link drain} can wait for it. */
@@ -58,7 +130,13 @@ export declare class WorkflowEngine {
58
130
  * Resume every run left incomplete by a crash or deploy. Called on boot. Completed steps
59
131
  * replay from their checkpoints, so only the work that had not finished runs again.
60
132
  */
61
- recoverIncomplete(): Promise<RunResult[]>;
133
+ recoverIncomplete(nowMs?: number): Promise<RunResult[]>;
134
+ /**
135
+ * Per-recovery bookkeeping (called once the lease is held): count the attempt, or — past
136
+ * `maxRecoveryAttempts` — move a poison pill to the `dead` dead-letter state. Returns a terminal
137
+ * result to skip the resume, or `undefined` to proceed.
138
+ */
139
+ private countRecovery;
62
140
  /**
63
141
  * Resume every suspended run whose durable timer is due. Call periodically (a poller) and on
64
142
  * boot. A run still not due re-suspends cheaply without running new work.
@@ -88,24 +166,55 @@ export declare class WorkflowEngine {
88
166
  * knowing about the child feature.
89
167
  */
90
168
  private notifyParent;
91
- /** Cancel a run (e.g. from the dashboard). Returns null if the run does not exist. */
92
- cancel(runId: string): Promise<RunResult | null>;
169
+ /**
170
+ * Cancel a run (e.g. from the dashboard). Returns null if the run does not exist. Pass
171
+ * `{ compensate: true }` to undo the saga first: the suspended run is resumed so its completed
172
+ * steps' compensations run in reverse (visible as `compensate:<step>` events), then it's marked
173
+ * cancelled. Without it, cancellation is immediate (no undo).
174
+ */
175
+ cancel(runId: string, opts?: {
176
+ compensate?: boolean;
177
+ }): Promise<RunResult | null>;
93
178
  /** Checkpoint a finished step and announce it — the two things that must always happen together. */
94
179
  private completeStep;
95
180
  /** Checkpoint a step that failed terminally, so the failure point is visible (not just the run). */
96
181
  private failStep;
97
182
  private execute;
98
- private makeCtx;
99
- /** Persist a completed timer checkpoint (a durable sleep / signal deadline) at a logical position. */
100
- private recordTimer;
101
- /** Persist a `pending` checkpoint marking a breakpoint, so it's visible (and resumable) in the UI. */
102
- private recordBreakpoint;
183
+ /**
184
+ * Run one saga compensation, retried up to `compensationRetries`, emitting a `compensate:<step>`
185
+ * step event for its outcome so a stranded undo is visible. Never throws — a permanently-failing
186
+ * compensation is skipped so it can't mask the original failure.
187
+ */
188
+ private runCompensation;
189
+ /** The seam handed to {@link createWorkflowCtx}: the authoring API reaches durability + lifecycle
190
+ * (checkpointing, dispatch, child start) through this, so the ctx primitives live in their own
191
+ * module and the engine stays the orchestrator. */
192
+ private get ctxHost();
103
193
  /**
104
194
  * Resume a run paused at a {@link WorkflowCtx.breakpoint} (e.g. the dashboard "continue" button).
105
195
  * Finds the run's pending breakpoint checkpoint and signals it. Returns null if the run isn't
106
196
  * paused at a breakpoint.
107
197
  */
108
198
  continue(runId: string): Promise<RunResult | null>;
199
+ /**
200
+ * Read the latest value a run published for `key` via {@link WorkflowCtx.setEvent} — a
201
+ * side-effect-free query of a live (or finished) run's state. Returns `undefined` if the run
202
+ * never published that key. The suspend-model counterpart of a Temporal query.
203
+ */
204
+ getEvent<TValue = unknown>(runId: string, key: string): Promise<TValue | undefined>;
205
+ /**
206
+ * Register a validator gating `engine.update(runId, name, …)` for runs of `workflow`. The
207
+ * validator runs BEFORE the update is delivered, so a rejection leaves the run untouched. One
208
+ * validator per (workflow, update name); registering again replaces it.
209
+ */
210
+ registerUpdateValidator<TArg>(workflow: string, name: string, validate: UpdateValidator<TArg>): void;
211
+ /**
212
+ * Deliver a validated update to the run waiting at `ctx.onUpdate(name)`. Runs the registered
213
+ * validator (if any) first: on rejection returns `{ accepted: false, reason }` without disturbing
214
+ * the run; otherwise delivers `arg` and resumes, returning `{ accepted: true, run }` (`run` is null
215
+ * if nothing was waiting — a too-early or duplicate update).
216
+ */
217
+ update(runId: string, name: string, arg: unknown): Promise<UpdateResult>;
109
218
  private callRemote;
110
219
  /**
111
220
  * Complete a durable remote step from its worker result and resume the run — runs on whichever
@@ -113,6 +222,8 @@ export declare class WorkflowEngine {
113
222
  * A no-op if the checkpoint isn't `pending` (a duplicate or late delivery).
114
223
  */
115
224
  private completeRemoteResult;
225
+ /** Release the flow-control slot a dispatched step held (if any), by its stepId. */
226
+ private releaseQueueSlot;
116
227
  /** In-memory await path for a remote step with a liveness `timeoutMs` (re-dispatch on timeout). */
117
228
  private callRemoteInMemory;
118
229
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EAEZ,cAAc,EACd,cAAc,EAGd,SAAS,EACT,UAAU,EACV,SAAS,EAGT,SAAS,EACT,YAAY,EACZ,eAAe,EACf,WAAW,EAEZ,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,SAAS,CAAC;AAS5D,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAoCzE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,UAAU,CAAC;IAClB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;IACrB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mGAAmG;IACnG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACvC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAA4B;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAA2B;IACxD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyC;IACnE,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,sFAAsF;IACtF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,mGAAmG;IACnG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsC;IACtE,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsC;IACvE,wFAAwF;IACxF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD,uFAAuF;IACvF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAC7D,gGAAgG;IAChG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAS;gBAEb,IAAI,EAAE,kBAAkB;IAqDpC,mGAAmG;IACnG,OAAO,CAAC,eAAe;IAUvB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI;IAO7D;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAIxC,sEAAsE;IACtE,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI;IAK/C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAKvD;0FACsF;IACtF,OAAO,CAAC,IAAI;IAYZ;wGACoG;IACpG,OAAO,CAAC,OAAO;IAUT,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAwB1E,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAoB/C,qEAAqE;IACrE,OAAO,CAAC,KAAK;IAMb;;;;OAIG;IACG,KAAK,CAAC,SAAS,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9C;;;OAGG;IACG,iBAAiB,CAAC,KAAK,GAAE,MAAqB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAM3E;;;;OAIG;YACW,aAAa;IAiB3B;;;OAGG;IACG,eAAe,CAAC,KAAK,GAAE,MAAqB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAIzE;;;OAGG;YACW,YAAY;IAsB1B;;;OAGG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAexE;;;;OAIG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAO3F,6FAA6F;IACvF,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAIrF;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IA+BvF,oGAAoG;YACtF,YAAY;IA6B1B,oGAAoG;YACtF,QAAQ;YA6BR,OAAO;IAiErB;;;;OAIG;YACW,eAAe;IA+B7B;;wDAEoD;IACpD,OAAO,KAAK,OAAO,GAclB;IAED;;;;OAIG;IACG,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAOxD;;;;OAIG;IACG,QAAQ,CAAC,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IASzF;;;;OAIG;IACH,uBAAuB,CAAC,IAAI,EAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC,GAC9B,IAAI;IAIP;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;YAgBhE,UAAU;IAoFxB;;;;OAIG;YACW,oBAAoB;IAmClC,oFAAoF;IACpF,OAAO,CAAC,gBAAgB;IAOxB,mGAAmG;YACrF,kBAAkB;IAkEhC;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;CAoC3B;AAED,8EAA8E;AAC9E,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;gBACnB,SAAS,CAAC,EAAE,SAAS;CAKlC"}