@dudousxd/nestjs-durable-core 0.5.0 → 0.7.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 +117 -10
  14. package/dist/engine.d.ts.map +1 -1
  15. package/dist/engine.js +287 -276
  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 +113 -17
  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 +6 -4
  36. package/dist/testing/in-memory-transport.d.ts.map +1 -1
  37. package/dist/testing/in-memory-transport.js +4 -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, WorkflowRun } 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. */
@@ -33,6 +76,16 @@ export declare class WorkflowEngine {
33
76
  private readonly listeners;
34
77
  /** Callbacks notified (on any instance) when a run is cancelled — for cooperative cancellation. */
35
78
  private readonly cancelListeners;
79
+ /** Notified when a run is dead-lettered (moved to `dead`) — a hook for a DLQ handler. */
80
+ private readonly deadListeners;
81
+ /** Validators gating `engine.update`, keyed by `<workflow>:<updateName>`. */
82
+ private readonly updateValidators;
83
+ /** Runs being cancelled WITH saga compensation — see `cancel({ compensate: true })`. */
84
+ private readonly cancelRequested;
85
+ /** Flow-control queues for remote steps, keyed by name (see {@link registerQueue}). */
86
+ private readonly queues;
87
+ /** Which queue a dispatched step took a slot from, by stepId — so the result can release it. */
88
+ private readonly stepQueue;
36
89
  /** Executions currently in flight, so a graceful shutdown can wait for them to settle. */
37
90
  private readonly inflight;
38
91
  private draining;
@@ -45,6 +98,12 @@ export declare class WorkflowEngine {
45
98
  * runs start on the newest registered version.
46
99
  */
47
100
  register(name: string, version: string, fn: WorkflowFn): void;
101
+ /**
102
+ * Register a flow-control queue referenced by `ctx.call(step, input, { queue })`. Caps concurrent
103
+ * in-flight steps and/or the admission rate; blocked calls re-suspend and retry, so the limit is
104
+ * durable. Per engine instance (see {@link QueueConfig}). Registering the same name replaces it.
105
+ */
106
+ registerQueue(config: QueueConfig): void;
48
107
  /** Subscribe to lifecycle events. Returns an unsubscribe function. */
49
108
  subscribe(listener: EngineListener): () => void;
50
109
  /**
@@ -53,6 +112,15 @@ export declare class WorkflowEngine {
53
112
  * instead of finishing it just to have the result discarded. Returns an unsubscribe function.
54
113
  */
55
114
  onCancel(listener: (runId: string) => void): () => void;
115
+ /**
116
+ * Be notified when a run is **dead-lettered** — moved to `dead` after exceeding
117
+ * `maxRecoveryAttempts`. The listener receives the dead run (status `dead`, with its error), so a
118
+ * DLQ handler can do something other than just leaving it parked: alert, push to a real queue, or
119
+ * start a dead-letter workflow (e.g. `engine.onDead((run) => engine.start('pipeline-dlq', run, ...))`).
120
+ * Returns an unsubscribe function.
121
+ */
122
+ onDead(listener: (run: WorkflowRun) => void): () => void;
123
+ private notifyDead;
56
124
  /** Emit a locally-produced lifecycle event: deliver to subscribers AND broadcast it on the
57
125
  * control plane so other instances (e.g. a dashboard pod) can live-tail this run. */
58
126
  private emit;
@@ -73,7 +141,13 @@ export declare class WorkflowEngine {
73
141
  * Resume every run left incomplete by a crash or deploy. Called on boot. Completed steps
74
142
  * replay from their checkpoints, so only the work that had not finished runs again.
75
143
  */
76
- recoverIncomplete(): Promise<RunResult[]>;
144
+ recoverIncomplete(nowMs?: number): Promise<RunResult[]>;
145
+ /**
146
+ * Per-recovery bookkeeping (called once the lease is held): count the attempt, or — past
147
+ * `maxRecoveryAttempts` — move a poison pill to the `dead` dead-letter state. Returns a terminal
148
+ * result to skip the resume, or `undefined` to proceed.
149
+ */
150
+ private countRecovery;
77
151
  /**
78
152
  * Resume every suspended run whose durable timer is due. Call periodically (a poller) and on
79
153
  * boot. A run still not due re-suspends cheaply without running new work.
@@ -103,24 +177,55 @@ export declare class WorkflowEngine {
103
177
  * knowing about the child feature.
104
178
  */
105
179
  private notifyParent;
106
- /** Cancel a run (e.g. from the dashboard). Returns null if the run does not exist. */
107
- cancel(runId: string): Promise<RunResult | null>;
180
+ /**
181
+ * Cancel a run (e.g. from the dashboard). Returns null if the run does not exist. Pass
182
+ * `{ compensate: true }` to undo the saga first: the suspended run is resumed so its completed
183
+ * steps' compensations run in reverse (visible as `compensate:<step>` events), then it's marked
184
+ * cancelled. Without it, cancellation is immediate (no undo).
185
+ */
186
+ cancel(runId: string, opts?: {
187
+ compensate?: boolean;
188
+ }): Promise<RunResult | null>;
108
189
  /** Checkpoint a finished step and announce it — the two things that must always happen together. */
109
190
  private completeStep;
110
191
  /** Checkpoint a step that failed terminally, so the failure point is visible (not just the run). */
111
192
  private failStep;
112
193
  private execute;
113
- private makeCtx;
114
- /** Persist a completed timer checkpoint (a durable sleep / signal deadline) at a logical position. */
115
- private recordTimer;
116
- /** Persist a `pending` checkpoint marking a breakpoint, so it's visible (and resumable) in the UI. */
117
- private recordBreakpoint;
194
+ /**
195
+ * Run one saga compensation, retried up to `compensationRetries`, emitting a `compensate:<step>`
196
+ * step event for its outcome so a stranded undo is visible. Never throws — a permanently-failing
197
+ * compensation is skipped so it can't mask the original failure.
198
+ */
199
+ private runCompensation;
200
+ /** The seam handed to {@link createWorkflowCtx}: the authoring API reaches durability + lifecycle
201
+ * (checkpointing, dispatch, child start) through this, so the ctx primitives live in their own
202
+ * module and the engine stays the orchestrator. */
203
+ private get ctxHost();
118
204
  /**
119
205
  * Resume a run paused at a {@link WorkflowCtx.breakpoint} (e.g. the dashboard "continue" button).
120
206
  * Finds the run's pending breakpoint checkpoint and signals it. Returns null if the run isn't
121
207
  * paused at a breakpoint.
122
208
  */
123
209
  continue(runId: string): Promise<RunResult | null>;
210
+ /**
211
+ * Read the latest value a run published for `key` via {@link WorkflowCtx.setEvent} — a
212
+ * side-effect-free query of a live (or finished) run's state. Returns `undefined` if the run
213
+ * never published that key. The suspend-model counterpart of a Temporal query.
214
+ */
215
+ getEvent<TValue = unknown>(runId: string, key: string): Promise<TValue | undefined>;
216
+ /**
217
+ * Register a validator gating `engine.update(runId, name, …)` for runs of `workflow`. The
218
+ * validator runs BEFORE the update is delivered, so a rejection leaves the run untouched. One
219
+ * validator per (workflow, update name); registering again replaces it.
220
+ */
221
+ registerUpdateValidator<TArg>(workflow: string, name: string, validate: UpdateValidator<TArg>): void;
222
+ /**
223
+ * Deliver a validated update to the run waiting at `ctx.onUpdate(name)`. Runs the registered
224
+ * validator (if any) first: on rejection returns `{ accepted: false, reason }` without disturbing
225
+ * the run; otherwise delivers `arg` and resumes, returning `{ accepted: true, run }` (`run` is null
226
+ * if nothing was waiting — a too-early or duplicate update).
227
+ */
228
+ update(runId: string, name: string, arg: unknown): Promise<UpdateResult>;
124
229
  private callRemote;
125
230
  /**
126
231
  * Complete a durable remote step from its worker result and resume the run — runs on whichever
@@ -128,6 +233,8 @@ export declare class WorkflowEngine {
128
233
  * A no-op if the checkpoint isn't `pending` (a duplicate or late delivery).
129
234
  */
130
235
  private completeRemoteResult;
236
+ /** Release the flow-control slot a dispatched step held (if any), by its stepId. */
237
+ private releaseQueueSlot;
131
238
  /** In-memory await path for a remote step with a liveness `timeoutMs` (re-dispatch on timeout). */
132
239
  private callRemoteInMemory;
133
240
  /**
@@ -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":"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"}