@dudousxd/nestjs-durable-core 0.58.0 → 0.59.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.
- package/dist/index.cjs +514 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +459 -3
- package/dist/index.d.ts +459 -3
- package/dist/index.js +498 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -161,6 +161,243 @@ declare class InMemoryAdmissionBackend implements AdmissionBackend {
|
|
|
161
161
|
release(queue: string, _slotId: string): Promise<void>;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Worker/control-plane handshake descriptor — the single source of truth for routing, compatibility
|
|
166
|
+
* and observability across a store-less durable cluster (design §7.1). Pure data + a deterministic,
|
|
167
|
+
* order-insensitive content hash; NO transport, NO I/O. Every field is part of the cross-language
|
|
168
|
+
* wire contract — the adonis + python SDKs build the byte-identical shape (design §7.8), and the
|
|
169
|
+
* golden fixtures in `<repo>/fixtures/wire/` pin the exact bytes all three SDKs must agree on.
|
|
170
|
+
*/
|
|
171
|
+
/**
|
|
172
|
+
* A worker's (or control-plane's) advertised identity, wire-protocol support, feature capabilities
|
|
173
|
+
* and registered handlers. Published on startup + on change (design §7.2) and consumed by
|
|
174
|
+
* {@link negotiate} (compat) and the capability-aware router (design §7.5). Exactly the §7.1 shape.
|
|
175
|
+
*/
|
|
176
|
+
interface WorkerDescriptor {
|
|
177
|
+
/** Stable id for this process in the fleet (mirrors aviary's per-instance heartbeat key). */
|
|
178
|
+
instanceId: string;
|
|
179
|
+
/** Execution runtime — a `python` worker and a `node` control-plane interoperate over the wire. */
|
|
180
|
+
runtime: 'node' | 'python';
|
|
181
|
+
/** Which SDK + version produced this descriptor. Observability only; never gates dispatch. */
|
|
182
|
+
sdk: {
|
|
183
|
+
name: string;
|
|
184
|
+
version: string;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Wire-protocol majors this side speaks. `version` is its preferred/current major; `range` is the
|
|
188
|
+
* inclusive `[min, max]` band it can negotiate down/up to. Overlap of two ranges is what makes two
|
|
189
|
+
* sides compatible (design §7.4); `version` is informational.
|
|
190
|
+
*/
|
|
191
|
+
protocol: {
|
|
192
|
+
version: number;
|
|
193
|
+
range: [number, number];
|
|
194
|
+
};
|
|
195
|
+
/** Named features advertised: `'saga'`, `'signals'`, `'search-attr-v2'`, `'priority'`, … A modern
|
|
196
|
+
* worker MAY advertise `[]` (no named features); an ABSENT field means "legacy v1" — see
|
|
197
|
+
* {@link normalizeDescriptor}. Order-insensitive: treated as a set. */
|
|
198
|
+
capabilities: string[];
|
|
199
|
+
/** Registered workflow handler names → routing targets. Order-insensitive (a set). */
|
|
200
|
+
workflows: string[];
|
|
201
|
+
/** Registered step handler names → routing targets. Order-insensitive (a set). */
|
|
202
|
+
steps: string[];
|
|
203
|
+
/** Optional routing partition (queue/group sharding). */
|
|
204
|
+
partition?: string;
|
|
205
|
+
/** Optional tenant namespace this instance serves. */
|
|
206
|
+
namespace?: string;
|
|
207
|
+
/** Process start time (epoch ms) — a restart changes it, so it participates in the content hash. */
|
|
208
|
+
startedAt: number;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* The current wire-protocol major. The whole protocol as it exists today is defined as **v1**; the
|
|
212
|
+
* handshake exists so a future **v2 breaking change** is detectable rather than silently corrupting
|
|
213
|
+
* (design §7.7).
|
|
214
|
+
*/
|
|
215
|
+
declare const CURRENT_PROTOCOL_VERSION = 1;
|
|
216
|
+
/**
|
|
217
|
+
* The protocol band assumed for a descriptor that omits `protocol` entirely — an existing aviary
|
|
218
|
+
* worker that predates the handshake. Absence = **legacy v1 baseline, assume compatible** (§7.7).
|
|
219
|
+
*/
|
|
220
|
+
declare const LEGACY_V1_PROTOCOL: WorkerDescriptor['protocol'];
|
|
221
|
+
/**
|
|
222
|
+
* The feature set a legacy (pre-handshake) worker is assumed to advertise when its `capabilities`
|
|
223
|
+
* field is ABSENT. These are the durable primitives aviary has shipped since v1, so a legacy worker
|
|
224
|
+
* can still be routed work that `requires` them (design §7.5/§7.7).
|
|
225
|
+
*
|
|
226
|
+
* CROSS-SDK CONTRACT — this list is the canonical "what a v1 worker can do" baseline and MUST stay
|
|
227
|
+
* byte-identical across the adonis + nestjs + python SDKs. It is the ACTUAL aviary durable v1
|
|
228
|
+
* execution surface (each name maps to a shipped primitive: saga/compensation, signals,
|
|
229
|
+
* search-attributes, priority/fairness, entities, child-workflows, singleton gating, cron schedules,
|
|
230
|
+
* continue-as-new, queries, cooperative cancellation). `search-attr-v2` is a MODERN capability layered
|
|
231
|
+
* on top and is deliberately NOT in the v1 baseline — a v1 worker only guarantees the v1
|
|
232
|
+
* `search-attributes` surface.
|
|
233
|
+
*/
|
|
234
|
+
declare const LEGACY_V1_CAPABILITIES: readonly string[];
|
|
235
|
+
/**
|
|
236
|
+
* A raw, possibly-partial descriptor as it may arrive off the wire from an older SDK: `protocol`
|
|
237
|
+
* and/or `capabilities` may be missing. {@link normalizeDescriptor} fills the legacy-v1 defaults.
|
|
238
|
+
*/
|
|
239
|
+
type RawWorkerDescriptor = Omit<Partial<WorkerDescriptor>, 'instanceId' | 'runtime'> & {
|
|
240
|
+
instanceId: string;
|
|
241
|
+
runtime: 'node' | 'python';
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* True when a descriptor predates the handshake — it carries no `protocol` field. Such a descriptor
|
|
245
|
+
* is treated as legacy v1 and assumed compatible (design §7.7).
|
|
246
|
+
*/
|
|
247
|
+
declare function isLegacyDescriptor(raw: RawWorkerDescriptor | WorkerDescriptor): boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Fill legacy-v1 defaults so downstream logic always sees a complete {@link WorkerDescriptor}:
|
|
250
|
+
* - absent `protocol` → {@link LEGACY_V1_PROTOCOL} (assume-compatible v1 baseline),
|
|
251
|
+
* - absent `capabilities` → {@link LEGACY_V1_CAPABILITIES} (a modern `[]` is preserved as-is),
|
|
252
|
+
* - absent `workflows`/`steps` → `[]`, absent `sdk` → an `unknown` marker, absent `startedAt` → `0`.
|
|
253
|
+
*
|
|
254
|
+
* The undefined-vs-`[]` distinction is deliberate: an absent field means "legacy, doesn't advertise
|
|
255
|
+
* this axis"; an explicit empty array means "modern SDK that genuinely advertises nothing".
|
|
256
|
+
*/
|
|
257
|
+
declare function normalizeDescriptor(raw: RawWorkerDescriptor | WorkerDescriptor): WorkerDescriptor;
|
|
258
|
+
/**
|
|
259
|
+
* Compact, liveness lifecycle status carried on the cheap steady-state heartbeat (design §7.2).
|
|
260
|
+
* Distinct from aviary's rich `WorkerStatus` object (owned by the transport layer): this is the
|
|
261
|
+
* lightweight two-tier advertisement, whose job is to carry the {@link descriptorHash} ETag.
|
|
262
|
+
*/
|
|
263
|
+
type WorkerLifecycle = 'up' | 'draining' | 'quiescing' | 'stopped';
|
|
264
|
+
/**
|
|
265
|
+
* The two-tier heartbeat payload (design §7.2): a cheap `{ ts, status, descriptorHash }` beaten every
|
|
266
|
+
* ~10s. The `descriptorHash` is an **ETag** — the control-plane re-reads the full (expensive)
|
|
267
|
+
* descriptor only when this hash changes, keeping steady-state chatter tiny.
|
|
268
|
+
*/
|
|
269
|
+
interface HeartbeatStatus {
|
|
270
|
+
/** Beat time, epoch ms. */
|
|
271
|
+
ts: number;
|
|
272
|
+
/** Compact lifecycle status. */
|
|
273
|
+
status: WorkerLifecycle;
|
|
274
|
+
/** ETag over the full descriptor — see {@link descriptorHash}. */
|
|
275
|
+
descriptorHash: string;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Stable ETag over a descriptor's content (design §7.2). **Order-insensitive** over the set-valued
|
|
279
|
+
* fields (`capabilities`/`workflows`/`steps`) — the same members in any order yield the same hash —
|
|
280
|
+
* and stable across the object's key insertion order. Any change to a routing/compat-relevant field
|
|
281
|
+
* (including `startedAt` on restart) changes the hash, which is what triggers a full re-read.
|
|
282
|
+
*
|
|
283
|
+
* Accepts a raw/partial descriptor too: it is normalized first, so a legacy descriptor hashes as its
|
|
284
|
+
* v1 baseline.
|
|
285
|
+
*/
|
|
286
|
+
declare function descriptorHash(descriptor: RawWorkerDescriptor | WorkerDescriptor): string;
|
|
287
|
+
/**
|
|
288
|
+
* Build the compact two-tier heartbeat for a descriptor, stamping the ETag (design §7.2). `ts`
|
|
289
|
+
* defaults to now and `status` to `'up'`.
|
|
290
|
+
*/
|
|
291
|
+
declare function heartbeatStatus(descriptor: RawWorkerDescriptor | WorkerDescriptor, opts?: {
|
|
292
|
+
ts?: number;
|
|
293
|
+
status?: WorkerLifecycle;
|
|
294
|
+
}): HeartbeatStatus;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Capability- & protocol-aware dispatch planning (design §7.5/§7.6). Sits BETWEEN the pure handshake
|
|
298
|
+
* (`resolveRouting`/`negotiate`, `./{routing,negotiate}`) and the engine's dispatch path: given a
|
|
299
|
+
* step's/workflow's required capabilities and the LIVE worker descriptors for its routing token,
|
|
300
|
+
* decide whether a live worker can actually run it — and if not, produce the LOUD, structured reason
|
|
301
|
+
* the engine parks the run `blocked` with (never a silent hang into a queue nobody consumes).
|
|
302
|
+
*
|
|
303
|
+
* Pure logic + a small control-plane descriptor factory: no transport, no store, no I/O. The engine
|
|
304
|
+
* feeds in descriptors it read off the broker and acts on the returned plan.
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Build the control-plane's OWN handshake descriptor — the side the engine negotiates AGAINST each
|
|
309
|
+
* worker (design §7.3). The CP advertises the protocol band it speaks so a worker stuck on an
|
|
310
|
+
* incompatible major is detected instead of dispatched into (design §7.4). Capabilities default to
|
|
311
|
+
* empty (the CP demands nothing of itself); `partition`/`namespace` scope it to a pool when set.
|
|
312
|
+
*
|
|
313
|
+
* The CP is not a worker, so `workflows`/`steps` are empty and `runtime` is `node`. `startedAt`
|
|
314
|
+
* participates only in the descriptor hash (irrelevant for negotiation), so it defaults to `0` unless
|
|
315
|
+
* a caller wants a stable identity.
|
|
316
|
+
*/
|
|
317
|
+
declare function controlPlaneDescriptor(opts: {
|
|
318
|
+
instanceId: string;
|
|
319
|
+
/** SDK identity for observability (never gates dispatch). */
|
|
320
|
+
sdk?: {
|
|
321
|
+
name: string;
|
|
322
|
+
version: string;
|
|
323
|
+
};
|
|
324
|
+
/** Protocol majors the CP can negotiate. Defaults to the current single-major band `[v, v]`. */
|
|
325
|
+
protocol?: {
|
|
326
|
+
version: number;
|
|
327
|
+
range: [number, number];
|
|
328
|
+
};
|
|
329
|
+
/** Capabilities the CP itself advertises (rarely needed; the CP is a router, not an executor). */
|
|
330
|
+
capabilities?: string[];
|
|
331
|
+
partition?: string | undefined;
|
|
332
|
+
namespace?: string | undefined;
|
|
333
|
+
startedAt?: number;
|
|
334
|
+
}): WorkerDescriptor;
|
|
335
|
+
/** The structured delta a blocked-dispatch diagnostics event carries (design §7.6) — enough for the
|
|
336
|
+
* telescope timeline + dashboard health panel to render exactly WHY nobody could run the work, never
|
|
337
|
+
* a bare boolean. Serializable (plain data), so it rides an `EngineEvent`/control-plane message. */
|
|
338
|
+
interface DispatchDiagnostics {
|
|
339
|
+
/** Which machine code fired — a missing capability vs. an unbridgeable protocol gap. */
|
|
340
|
+
code: 'capability.unavailable' | 'protocol.incompatible';
|
|
341
|
+
/** The routing token the work would have been dispatched to. */
|
|
342
|
+
token: string;
|
|
343
|
+
/** The capabilities the handler required (de-duplicated). */
|
|
344
|
+
requires: string[];
|
|
345
|
+
/** How many live workers were advertising on this token at decision time. */
|
|
346
|
+
liveWorkers: number;
|
|
347
|
+
/** Required capabilities NOT advertised by ANY live worker (the `capability.unavailable` delta). */
|
|
348
|
+
missingCapabilities?: string[];
|
|
349
|
+
/** The protocol band the control-plane speaks (the `protocol.incompatible` delta). */
|
|
350
|
+
controlPlaneRange?: [number, number];
|
|
351
|
+
/** Protocol bands of the capable-but-incompatible workers (the `protocol.incompatible` delta). */
|
|
352
|
+
workerRanges?: [number, number][];
|
|
353
|
+
/** The control-plane descriptor negotiated against (attached wholesale for observability). */
|
|
354
|
+
controlPlane: WorkerDescriptor;
|
|
355
|
+
/** The live worker descriptors considered (attached wholesale — the full picture on the timeline). */
|
|
356
|
+
workers: WorkerDescriptor[];
|
|
357
|
+
}
|
|
358
|
+
/** At least one live worker can run the handler — dispatch proceeds as today. */
|
|
359
|
+
interface RoutableDispatch {
|
|
360
|
+
status: 'routable';
|
|
361
|
+
/** The normalized subset that is BOTH capable and protocol-compatible. */
|
|
362
|
+
workers: WorkerDescriptor[];
|
|
363
|
+
}
|
|
364
|
+
/** No live worker can run the handler — the engine parks the run `blocked` with this reason/delta. */
|
|
365
|
+
interface BlockedDispatch {
|
|
366
|
+
status: 'blocked';
|
|
367
|
+
code: 'capability.unavailable' | 'protocol.incompatible';
|
|
368
|
+
/** Dashboard/telescope copy, e.g. `blocked: no compatible worker (requires saga)`. */
|
|
369
|
+
reason: string;
|
|
370
|
+
requires: string[];
|
|
371
|
+
diagnostics: DispatchDiagnostics;
|
|
372
|
+
}
|
|
373
|
+
type DispatchPlan = RoutableDispatch | BlockedDispatch;
|
|
374
|
+
/**
|
|
375
|
+
* Thrown from deep in a `ctx.step` dispatch when {@link planDispatch} returns `blocked`, so the
|
|
376
|
+
* engine's run-execution catch can park the run `blocked` (with the carried plan) instead of writing
|
|
377
|
+
* a `pending` checkpoint + dispatching into a queue no live worker consumes. Distinct from
|
|
378
|
+
* `WorkflowSuspended` — a blocked run is re-driven by the blocked-recovery poll, not a durable timer.
|
|
379
|
+
*/
|
|
380
|
+
declare class WorkflowBlocked extends Error {
|
|
381
|
+
readonly plan: BlockedDispatch;
|
|
382
|
+
constructor(plan: BlockedDispatch);
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Decide whether a handler requiring `requires` can be dispatched to a token whose LIVE fleet is
|
|
386
|
+
* `liveDescriptors`, negotiating each candidate against the control-plane descriptor `cp`
|
|
387
|
+
* (design §7.4/§7.5).
|
|
388
|
+
*
|
|
389
|
+
* A worker is dispatchable iff it is BOTH capability-capable ({@link canRoute}) AND
|
|
390
|
+
* protocol-compatible ({@link negotiate} outcome ≠ `incompatible`). If ≥1 such worker exists →
|
|
391
|
+
* `routable`. Otherwise `blocked`, with the reason discriminated:
|
|
392
|
+
* - some workers had the capability but ALL are protocol-incompatible → `protocol.incompatible`;
|
|
393
|
+
* - otherwise (no live worker advertises every required capability) → `capability.unavailable`.
|
|
394
|
+
*
|
|
395
|
+
* Precondition (enforced by the caller): `liveDescriptors` is NON-EMPTY. An empty fleet means "no
|
|
396
|
+
* descriptors published" — the legacy/pre-handshake path — where the guard is intentionally skipped so
|
|
397
|
+
* existing workers keep flowing (design §7.7); the engine never calls this with an empty fleet.
|
|
398
|
+
*/
|
|
399
|
+
declare function planDispatch(requires: string[], liveDescriptors: readonly (RawWorkerDescriptor | WorkerDescriptor)[], cp: WorkerDescriptor, token: string): DispatchPlan;
|
|
400
|
+
|
|
164
401
|
/**
|
|
165
402
|
* Vendored subset of the Standard Schema spec (https://standardschema.dev) — the `~standard`
|
|
166
403
|
* property protocol implemented by zod 3.24+, valibot, arktype, and others. Vendored (rather than
|
|
@@ -271,6 +508,10 @@ interface StepConfig {
|
|
|
271
508
|
* worker dead and fails the dispatch with a `RemoteStepTimeout` (retryable — re-dispatches per
|
|
272
509
|
* `retries`). Omit to wait indefinitely. */
|
|
273
510
|
timeoutMs?: number | undefined;
|
|
511
|
+
/** Capabilities a live worker must advertise to run this step (handshake design §7.5). The
|
|
512
|
+
* control-plane routes the step only to capable+compatible workers; if descriptors are published
|
|
513
|
+
* on its group but none qualifies, the run parks `blocked`. Absent/empty = "runs anywhere". */
|
|
514
|
+
requires?: string[] | undefined;
|
|
274
515
|
}
|
|
275
516
|
/**
|
|
276
517
|
* A method carrying its `@Step`-stamped routing name (and, optionally, its dispatch policy).
|
|
@@ -342,7 +583,15 @@ type RunStatus =
|
|
|
342
583
|
* `cancelled` once compensation completes. A non-compensating cancel skips this and goes straight to
|
|
343
584
|
* `cancelled`.
|
|
344
585
|
*/
|
|
345
|
-
| 'cancelling'
|
|
586
|
+
| 'cancelling'
|
|
587
|
+
/**
|
|
588
|
+
* No live worker on the run's next-dispatch group is BOTH capability-capable and protocol-compatible
|
|
589
|
+
* (handshake design §7.5). NON-TERMINAL — the run wrote no `pending` checkpoint and dispatched
|
|
590
|
+
* nothing; it carries a `wakeAt` so the blocked-recovery poll re-drives it to re-check the live
|
|
591
|
+
* fleet, and proceeds the moment a capable+compatible worker appears. Only engaged when descriptors
|
|
592
|
+
* are actually published (a legacy/pre-handshake fleet skips the guard, design §7.7).
|
|
593
|
+
*/
|
|
594
|
+
| 'blocked' | 'completed' | 'failed' | 'cancelled'
|
|
346
595
|
/** Dead-letter: recovery gave up after `maxRecoveryAttempts` (a poison pill). Terminal; inspect it. */
|
|
347
596
|
| 'dead';
|
|
348
597
|
/** One execution of a workflow. The unit of durability and the unit shown in the dashboard. */
|
|
@@ -1179,6 +1428,14 @@ interface Transport {
|
|
|
1179
1428
|
* keyspace, so a group with workers but no engine-side registration (e.g. a local-step group)
|
|
1180
1429
|
* still surfaces. Pairs with {@link groupHealth}. */
|
|
1181
1430
|
listWorkerGroups?(): Promise<string[]>;
|
|
1431
|
+
/**
|
|
1432
|
+
* The live handshake {@link WorkerDescriptor}s advertised for `group` (design §7.2). Optional — only
|
|
1433
|
+
* broker transports that carry the two-tier descriptor advertisement (BullMQ) implement it; a pure
|
|
1434
|
+
* in-process transport returns nothing, so the engine's routing guard stays disengaged (legacy
|
|
1435
|
+
* assume-compatible, design §7.7). The engine feeds these into {@link planDispatch} to decide whether
|
|
1436
|
+
* a run can dispatch to `group` or must park `blocked`.
|
|
1437
|
+
*/
|
|
1438
|
+
readWorkerDescriptors?(group: string): Promise<WorkerDescriptor[]>;
|
|
1182
1439
|
/**
|
|
1183
1440
|
* DB-less tenant worker → control plane: publish a {@link StartRunMessage} requesting a new run.
|
|
1184
1441
|
* Optional — only transports that carry the hosted-control-plane protocol (P4) implement this.
|
|
@@ -1357,6 +1614,15 @@ interface StepOptions {
|
|
|
1357
1614
|
* window. Omit to wait indefinitely.
|
|
1358
1615
|
*/
|
|
1359
1616
|
timeoutMs?: number;
|
|
1617
|
+
/**
|
|
1618
|
+
* Capabilities a live worker MUST advertise to run this dispatched step (handshake design §7.5).
|
|
1619
|
+
* The control-plane routes the step only to workers whose descriptor advertises every name here;
|
|
1620
|
+
* if descriptors are published on the step's group but NONE is capability-capable + protocol-
|
|
1621
|
+
* compatible, the run parks `blocked` (never a silent hang) and the blocked-recovery poll re-drives
|
|
1622
|
+
* it when a capable worker appears. Absent/empty = "runs anywhere" (the default; backward-compatible
|
|
1623
|
+
* — a legacy fleet publishing no descriptors skips the guard entirely, design §7.7).
|
|
1624
|
+
*/
|
|
1625
|
+
requires?: string[];
|
|
1360
1626
|
/**
|
|
1361
1627
|
* Saga compensation: if this step completes but the run later **fails**, the engine runs the
|
|
1362
1628
|
* registered `compensate` callbacks in reverse order (undo what was done). Local steps only.
|
|
@@ -1446,6 +1712,9 @@ interface StepDispatchOpts {
|
|
|
1446
1712
|
* worker dead and fails the dispatch with a `RemoteStepTimeout` (retryable — re-dispatches per
|
|
1447
1713
|
* `retries`). Omit to wait indefinitely. Overrides the `@Step`-declared value. */
|
|
1448
1714
|
timeoutMs?: number;
|
|
1715
|
+
/** Capabilities a live worker must advertise to run this dispatch (handshake design §7.5). Overrides
|
|
1716
|
+
* the `@Step`-declared `requires`. Absent = inherit the def-level value (or "runs anywhere"). */
|
|
1717
|
+
requires?: string[];
|
|
1449
1718
|
}
|
|
1450
1719
|
/** What a saga undo handler receives: the compensated step's original input and its result — the
|
|
1451
1720
|
* ONE argument a compensation `@Step` is called with, so it's self-describing on the wire (a
|
|
@@ -1724,7 +1993,7 @@ type UpdateResult = {
|
|
|
1724
1993
|
accepted: true;
|
|
1725
1994
|
run: RunResult | null;
|
|
1726
1995
|
};
|
|
1727
|
-
type EngineEventType = 'run.started' | 'run.completed' | 'run.failed' | 'run.suspended' | 'step.started' | 'step.completed' | 'step.failed' | 'step.progress';
|
|
1996
|
+
type EngineEventType = 'run.started' | 'run.completed' | 'run.failed' | 'run.suspended' | 'step.started' | 'step.completed' | 'step.failed' | 'step.progress' | 'run.blocked';
|
|
1728
1997
|
/**
|
|
1729
1998
|
* A lifecycle event emitted by the engine. The observability surfaces (dashboard, OTel, the
|
|
1730
1999
|
* Telescope integration) all subscribe to these rather than reaching into the store.
|
|
@@ -1749,6 +2018,12 @@ interface EngineEvent {
|
|
|
1749
2018
|
/** The live step event carried by a `step.progress` (the single log line / sub-process outcome a
|
|
1750
2019
|
* running step just emitted). Absent on lifecycle events. */
|
|
1751
2020
|
event?: StepEvent | undefined;
|
|
2021
|
+
/** Capabilities the blocked dispatch required (on a `run.blocked` event). */
|
|
2022
|
+
requires?: string[] | undefined;
|
|
2023
|
+
/** The structured routing delta on a `run.blocked` event (design §7.6): which capability/protocol
|
|
2024
|
+
* gap fired, how many live workers were considered, and both descriptors — enough for the health
|
|
2025
|
+
* panel/telescope to render the reason. Absent on all other event types. */
|
|
2026
|
+
diagnostics?: DispatchDiagnostics | undefined;
|
|
1752
2027
|
at: Date;
|
|
1753
2028
|
}
|
|
1754
2029
|
type EngineListener = (event: EngineEvent) => void;
|
|
@@ -2067,6 +2342,14 @@ interface WorkflowEngineDeps {
|
|
|
2067
2342
|
* instead of re-dispatching forever. Default 10. Ignored when `remoteRedispatchMs` is unset.
|
|
2068
2343
|
*/
|
|
2069
2344
|
remoteRedispatchMax?: number | undefined;
|
|
2345
|
+
/**
|
|
2346
|
+
* How long (ms) a run parked `blocked` (no capability-capable + protocol-compatible live worker,
|
|
2347
|
+
* handshake design §7.5) waits before the blocked-recovery poll re-drives it to re-check the live
|
|
2348
|
+
* fleet. Default 5000. The run proceeds the moment a capable+compatible worker appears; until then it
|
|
2349
|
+
* re-parks with a fresh `wakeAt` each poll. Only relevant once a step/workflow declares `requires`
|
|
2350
|
+
* AND descriptors are published (a legacy fleet never parks blocked).
|
|
2351
|
+
*/
|
|
2352
|
+
blockedPollMs?: number | undefined;
|
|
2070
2353
|
/**
|
|
2071
2354
|
* Build the public callback URL for a `ctx.webhook()` token (e.g.
|
|
2072
2355
|
* ``(t) => `https://api.example.com/durable/webhooks/${t}` ``). Populates
|
|
@@ -2146,6 +2429,10 @@ declare class WorkflowEngine {
|
|
|
2146
2429
|
private readonly eventBufferTtlMs;
|
|
2147
2430
|
private readonly remoteRedispatchMs;
|
|
2148
2431
|
private readonly remoteRedispatchMax;
|
|
2432
|
+
/** How long a `blocked` run waits before the recovery poll re-checks the live fleet (design §7.5). */
|
|
2433
|
+
private readonly blockedPollMs;
|
|
2434
|
+
/** This engine's control-plane handshake descriptor — negotiated against each worker (design §7.3). */
|
|
2435
|
+
private readonly cpDescriptor;
|
|
2149
2436
|
private readonly webhookUrl?;
|
|
2150
2437
|
private readonly traceparent?;
|
|
2151
2438
|
private readonly context?;
|
|
@@ -2246,6 +2533,9 @@ declare class WorkflowEngine {
|
|
|
2246
2533
|
* in-app worker, pair a transport-backed {@link RemoteWorkflowExecutor} (group consumed by a
|
|
2247
2534
|
* worker that calls {@link workflowBody}) so the retained `fn` runs through the transport hop. */
|
|
2248
2535
|
executor?: WorkflowExecutor | undefined;
|
|
2536
|
+
/** Capabilities a live worker must advertise to run this workflow's turns (handshake §7.5).
|
|
2537
|
+
* Only meaningful with `group`/`executor` (a remote/group-served workflow). Absent = runs anywhere. */
|
|
2538
|
+
requires?: string[] | undefined;
|
|
2249
2539
|
}): void;
|
|
2250
2540
|
/**
|
|
2251
2541
|
* The retained in-process body for `name@version`, for an IN-APP worker that consumes this engine's
|
|
@@ -2268,6 +2558,8 @@ declare class WorkflowEngine {
|
|
|
2268
2558
|
singleton?: SingletonConfig;
|
|
2269
2559
|
executionTimeout?: string | number;
|
|
2270
2560
|
validateInput?: (input: unknown) => void | Promise<void>;
|
|
2561
|
+
/** Capabilities a live worker must advertise to run this remote workflow's turns (handshake §7.5). */
|
|
2562
|
+
requires?: string[];
|
|
2271
2563
|
}): void;
|
|
2272
2564
|
/**
|
|
2273
2565
|
* The convenience form of {@link registerRemote}: register a workflow whose body runs on a worker
|
|
@@ -2291,6 +2583,8 @@ declare class WorkflowEngine {
|
|
|
2291
2583
|
singleton?: SingletonConfig;
|
|
2292
2584
|
executionTimeout?: string | number;
|
|
2293
2585
|
validateInput?: (input: unknown) => void | Promise<void>;
|
|
2586
|
+
/** Capabilities a live worker must advertise to run this workflow's turns (handshake §7.5). */
|
|
2587
|
+
requires?: string[];
|
|
2294
2588
|
}): void;
|
|
2295
2589
|
/**
|
|
2296
2590
|
* Register a flow-control queue referenced by `ctx.step(step, input, { queue })`. Caps concurrent
|
|
@@ -2852,6 +3146,34 @@ declare class WorkflowEngine {
|
|
|
2852
3146
|
* if nothing was waiting — a too-early or duplicate update).
|
|
2853
3147
|
*/
|
|
2854
3148
|
update(runId: string, name: string, arg: unknown): Promise<UpdateResult>;
|
|
3149
|
+
/**
|
|
3150
|
+
* Plan a dispatch to `token` for a handler requiring `requires` (handshake design §7.5). Returns:
|
|
3151
|
+
* - `undefined` — NO live descriptors published on this token: the guard does not engage, so a
|
|
3152
|
+
* pre-handshake fleet (or an in-process transport that advertises none) keeps flowing exactly as
|
|
3153
|
+
* before (design §7.7);
|
|
3154
|
+
* - a `routable` plan — ≥1 live worker is capability-capable AND protocol-compatible (dispatch);
|
|
3155
|
+
* - a `blocked` plan — descriptors exist but none can run it (park the run, never dispatch into it).
|
|
3156
|
+
*/
|
|
3157
|
+
private planRoute;
|
|
3158
|
+
/** Throw {@link WorkflowBlocked} when no live worker can run a dispatch to `token` — so the caller's
|
|
3159
|
+
* run-execution catch parks the run `blocked` (with the plan) instead of persisting a `pending`
|
|
3160
|
+
* checkpoint + dispatching into a queue nobody consumes (design §7.5). A no-op when the guard does
|
|
3161
|
+
* not engage (no descriptors) or a capable+compatible worker exists. */
|
|
3162
|
+
private ensureRoutable;
|
|
3163
|
+
/**
|
|
3164
|
+
* Park a run `blocked` (handshake design §7.5/§7.6): no live worker on its next-dispatch group is
|
|
3165
|
+
* capability-capable + protocol-compatible. Persists the `blocked` status with a human reason + the
|
|
3166
|
+
* machine `code` + a `wakeAt` so the blocked-recovery poll re-drives it, emits the LOUD structured
|
|
3167
|
+
* `capability.unavailable`/`protocol.incompatible` diagnostics (both descriptors + the precise delta),
|
|
3168
|
+
* and releases the run lease so any instance can re-drive it. Re-checks the persisted status first so
|
|
3169
|
+
* a concurrent cancel/complete is never clobbered. `releaseRunLock` is idempotent, so a caller whose
|
|
3170
|
+
* own `finally` also releases (the run-execution path) is safe.
|
|
3171
|
+
*/
|
|
3172
|
+
private parkBlocked;
|
|
3173
|
+
/** Runs parked `blocked` whose recovery poll is due (`wakeAt <= nowMs`), namespace-scoped like
|
|
3174
|
+
* {@link resumeDueTimers}. Re-driving one re-checks the live fleet: it dispatches if a
|
|
3175
|
+
* capable+compatible worker has appeared, else re-parks with a fresh `wakeAt` (design §7.5). */
|
|
3176
|
+
private dueBlockedRuns;
|
|
2855
3177
|
private callRemote;
|
|
2856
3178
|
/** Enqueue a remote step task to its worker group via the transport pool. Shared by the initial
|
|
2857
3179
|
* dispatch, the opt-in self-heal re-dispatch (see `remoteRedispatchMs`), and the explicit
|
|
@@ -3092,6 +3414,140 @@ declare class ContinueAsNew extends Error {
|
|
|
3092
3414
|
constructor(input: unknown);
|
|
3093
3415
|
}
|
|
3094
3416
|
|
|
3417
|
+
/**
|
|
3418
|
+
* Bilateral compatibility negotiation between two handshake descriptors (design §7.3/§7.4). Pure
|
|
3419
|
+
* logic: given a local and a remote {@link WorkerDescriptor}, compute the negotiated session (highest
|
|
3420
|
+
* common protocol major + capability intersection) and classify it into one of three outcomes with a
|
|
3421
|
+
* precise, structured reason — never a bare boolean (design §7.6).
|
|
3422
|
+
*/
|
|
3423
|
+
|
|
3424
|
+
/**
|
|
3425
|
+
* The three compatibility outcomes (design §7.4):
|
|
3426
|
+
* - `compatible` — protocol ranges intersect + full capability parity → dispatch freely.
|
|
3427
|
+
* - `degraded` — ranges intersect but a capability is missing on one side → dispatch, but route
|
|
3428
|
+
* capability-requiring work only to capable workers (soft warning).
|
|
3429
|
+
* - `incompatible` — no protocol-range overlap → do NOT dispatch; red flag with the exact reason.
|
|
3430
|
+
*/
|
|
3431
|
+
type NegotiationOutcome = 'compatible' | 'degraded' | 'incompatible';
|
|
3432
|
+
/** Structured failure/warning payload — carries the precise delta so a diagnostics event can render
|
|
3433
|
+
* it on the timeline + dashboard health panel (design §7.6). Never a bare boolean. */
|
|
3434
|
+
interface NegotiationReason {
|
|
3435
|
+
/** Stable machine code for alerting/telescope. */
|
|
3436
|
+
code: 'protocol.incompatible' | 'capability.unavailable';
|
|
3437
|
+
/** Human-readable one-liner (dashboard/telescope copy). */
|
|
3438
|
+
message: string;
|
|
3439
|
+
/** The exact delta: which protocol ranges failed to overlap, or which capabilities are missing. */
|
|
3440
|
+
detail: {
|
|
3441
|
+
localRange?: [number, number];
|
|
3442
|
+
remoteRange?: [number, number];
|
|
3443
|
+
/** Capabilities the local side advertises that the remote lacks. */
|
|
3444
|
+
missingOnRemote?: string[];
|
|
3445
|
+
/** Capabilities the remote side advertises that the local lacks. */
|
|
3446
|
+
missingOnLocal?: string[];
|
|
3447
|
+
/** Explicitly-required capabilities not satisfied by the negotiated session. */
|
|
3448
|
+
missingRequired?: string[];
|
|
3449
|
+
};
|
|
3450
|
+
}
|
|
3451
|
+
/** The negotiated session + full delta between two sides. Carries both normalized descriptors so a
|
|
3452
|
+
* downstream diagnostics event can attach them wholesale (design §7.6). */
|
|
3453
|
+
interface NegotiationResult {
|
|
3454
|
+
outcome: NegotiationOutcome;
|
|
3455
|
+
/** Highest common protocol major, or `null` when ranges do not overlap (incompatible). */
|
|
3456
|
+
negotiatedProtocol: number | null;
|
|
3457
|
+
protocol: {
|
|
3458
|
+
localRange: [number, number];
|
|
3459
|
+
remoteRange: [number, number];
|
|
3460
|
+
};
|
|
3461
|
+
capabilities: {
|
|
3462
|
+
/** Intersection — the capabilities the negotiated session can rely on everywhere. */
|
|
3463
|
+
shared: string[];
|
|
3464
|
+
/** Local advertises, remote lacks. */
|
|
3465
|
+
missingOnRemote: string[];
|
|
3466
|
+
/** Remote advertises, local lacks. */
|
|
3467
|
+
missingOnLocal: string[];
|
|
3468
|
+
};
|
|
3469
|
+
/** Present for `degraded` + `incompatible`; absent for `compatible`. */
|
|
3470
|
+
reason?: NegotiationReason;
|
|
3471
|
+
local: WorkerDescriptor;
|
|
3472
|
+
remote: WorkerDescriptor;
|
|
3473
|
+
}
|
|
3474
|
+
interface NegotiateOptions {
|
|
3475
|
+
/**
|
|
3476
|
+
* Capabilities the local side needs the negotiated session to provide. A required capability the
|
|
3477
|
+
* remote lacks degrades the session (dispatch generally, but capability-requiring runs park via
|
|
3478
|
+
* the router, design §7.5) — it never, on its own, makes the pair *incompatible*: only a protocol
|
|
3479
|
+
* range gap does that (design §7.4).
|
|
3480
|
+
*/
|
|
3481
|
+
required?: string[];
|
|
3482
|
+
}
|
|
3483
|
+
/**
|
|
3484
|
+
* Negotiate compatibility between `local` and `remote` (design §7.3/§7.4). Accepts raw/partial
|
|
3485
|
+
* descriptors (a missing `protocol`/`capabilities` is normalized to the legacy-v1 baseline, so a
|
|
3486
|
+
* legacy peer negotiates as **assume-compatible**, design §7.7).
|
|
3487
|
+
*
|
|
3488
|
+
* Outcome logic:
|
|
3489
|
+
* 1. no protocol-range overlap → `incompatible` (`protocol.incompatible`);
|
|
3490
|
+
* 2. else if a `required` capability is missing on the remote → `degraded` (`capability.unavailable`);
|
|
3491
|
+
* 3. else if the capability sets differ at all (either direction) → `degraded`;
|
|
3492
|
+
* 4. else full parity → `compatible`.
|
|
3493
|
+
*
|
|
3494
|
+
* **Bilateral-symmetric** on outcome for the parity path: `negotiate(a, b).outcome ===
|
|
3495
|
+
* negotiate(b, a).outcome` (the `missingOnLocal`/`missingOnRemote` delta swaps). `required` is the
|
|
3496
|
+
* caller's own need and intentionally asymmetric.
|
|
3497
|
+
*/
|
|
3498
|
+
declare function negotiate(localRaw: RawWorkerDescriptor | WorkerDescriptor, remoteRaw: RawWorkerDescriptor | WorkerDescriptor, opts?: NegotiateOptions): NegotiationResult;
|
|
3499
|
+
|
|
3500
|
+
/**
|
|
3501
|
+
* Capability-aware routing (design §7.5). A workflow/step handler may declare
|
|
3502
|
+
* `requires: ['saga', 'search-attr-v2']`; the control-plane dispatches only to workers whose
|
|
3503
|
+
* descriptor advertises every required capability. If no live capable worker exists the run must
|
|
3504
|
+
* **park as `blocked`** with a precise reason (visible in the dashboard) — never a silent hang.
|
|
3505
|
+
*
|
|
3506
|
+
* Pure logic: no transport, no store. Consumers (the dispatcher/provider) feed live descriptors in.
|
|
3507
|
+
*/
|
|
3508
|
+
|
|
3509
|
+
/** A handler's capability demand — either a bare list, or anything carrying a `requires` array
|
|
3510
|
+
* (a workflow/step ref). An absent/empty list means "runs anywhere" (design §7.5). */
|
|
3511
|
+
type CapabilityRequirement = string[] | {
|
|
3512
|
+
requires?: string[];
|
|
3513
|
+
};
|
|
3514
|
+
/** Normalize the two accepted shapes to a de-duplicated list of required capability names. */
|
|
3515
|
+
declare function requiredCapabilities(handler: CapabilityRequirement): string[];
|
|
3516
|
+
/**
|
|
3517
|
+
* Can `worker` run a handler with these requirements? True iff the worker's (normalized) descriptor
|
|
3518
|
+
* advertises **every** required capability. A legacy worker (no `capabilities` field) is normalized
|
|
3519
|
+
* to the v1 baseline first (design §7.7), so it can still run baseline-only work.
|
|
3520
|
+
*/
|
|
3521
|
+
declare function canRoute(handler: CapabilityRequirement, worker: RawWorkerDescriptor | WorkerDescriptor): boolean;
|
|
3522
|
+
/**
|
|
3523
|
+
* The capabilities a handler requires that `worker` does NOT advertise — the precise routing delta.
|
|
3524
|
+
* Empty iff {@link canRoute} is true.
|
|
3525
|
+
*/
|
|
3526
|
+
declare function missingCapabilities(handler: CapabilityRequirement, worker: RawWorkerDescriptor | WorkerDescriptor): string[];
|
|
3527
|
+
/** Filter a fleet down to the workers that can run a handler (design §7.5). */
|
|
3528
|
+
declare function capableWorkers<T extends RawWorkerDescriptor | WorkerDescriptor>(handler: CapabilityRequirement, workers: readonly T[]): T[];
|
|
3529
|
+
/** A run is dispatchable — at least one live worker can execute the handler. */
|
|
3530
|
+
interface RoutableResolution {
|
|
3531
|
+
status: 'routable';
|
|
3532
|
+
/** The normalized subset of the fleet that can run it. */
|
|
3533
|
+
workers: WorkerDescriptor[];
|
|
3534
|
+
requires: string[];
|
|
3535
|
+
}
|
|
3536
|
+
/** No live capable worker — the run parks as `blocked` with a human reason (design §7.5). */
|
|
3537
|
+
interface BlockedResolution {
|
|
3538
|
+
status: 'blocked';
|
|
3539
|
+
/** Exactly the dashboard copy: `blocked: no compatible worker (requires <caps>)`. */
|
|
3540
|
+
reason: string;
|
|
3541
|
+
requires: string[];
|
|
3542
|
+
}
|
|
3543
|
+
type RoutingResolution = RoutableResolution | BlockedResolution;
|
|
3544
|
+
/**
|
|
3545
|
+
* Decide whether a handler can be dispatched to the given live fleet (design §7.5). Returns
|
|
3546
|
+
* `routable` with the capable subset, or `blocked` with a precise reason when nobody can run it —
|
|
3547
|
+
* so the run parks visibly instead of hanging silently. An empty fleet always blocks.
|
|
3548
|
+
*/
|
|
3549
|
+
declare function resolveRouting(handler: CapabilityRequirement, workers: readonly (RawWorkerDescriptor | WorkerDescriptor)[]): RoutingResolution;
|
|
3550
|
+
|
|
3095
3551
|
/** Canonical step id — the stable identity of a step within a run, used for dedupe and
|
|
3096
3552
|
* correlation. The format is part of the cross-language wire contract (Python builds the same). */
|
|
3097
3553
|
declare function stepId(runId: string, seq: number): string;
|
|
@@ -3761,4 +4217,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
|
|
|
3761
4217
|
onControl(handler: (msg: ControlMessage) => void): void;
|
|
3762
4218
|
}
|
|
3763
4219
|
|
|
3764
|
-
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, CONTROL_FLOW_SIGNAL, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DurableTopology, type DurableWebhook, DurableWorkflow, EVENT_BUFFER_SCAN_LIMIT, EVENT_TOKEN_PREFIX, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, EventAccumulators, type EventBatchConfig, FatalError, GatherError, type GroupHealth, type Heartbeat, type HistoryEvent, InMemoryAdmissionBackend, InMemoryStateStore, InMemoryTransport, type InferSearchAttributes, type MetricsCollector, type MetricsSnapshot, type NamedTransport, NonDeterminismError, type PayloadCodec, type QueueConfig, QueueController, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, type ScheduledWorkflow, type SearchAttributes, type SearchAttributesSchema, SignalTimeoutError, type SignalWaiter, type SingletonConfig, SingletonQueueFullError, 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 StepUndo, type StoreTransaction, type SubProcessHandle, TERMINAL_RUN_STATUSES, TRANSPORT, TRANSPORT_CANONICAL, type TenantEvent, type Transport, type UndoOf, type UpdateResult, type UpdateValidator, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerHeartbeat, type WorkerStatus, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, applyAttributeQuery, attributeColumnFor, attributeOperand, bindWorkflowClass, breakpointToken, classifyWaiterToken, collectMetrics, createStepLogger, currentWorkflowCtx, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, indexWaitersByRun, isEventToken, isWorkflowControlFlowSignal, matchesAttributes, normalizeAttributeRows, parseDuration, prevCronFireMs, readSearchAttributes, resolveRunWaiting, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, tenantGroup, workflowName };
|
|
4220
|
+
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DispatchDiagnostics, type DispatchPlan, type DurableTopology, type DurableWebhook, DurableWorkflow, EVENT_BUFFER_SCAN_LIMIT, EVENT_TOKEN_PREFIX, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, EventAccumulators, type EventBatchConfig, FatalError, GatherError, type GroupHealth, type Heartbeat, type HeartbeatStatus, type HistoryEvent, InMemoryAdmissionBackend, InMemoryStateStore, InMemoryTransport, type InferSearchAttributes, LEGACY_V1_CAPABILITIES, LEGACY_V1_PROTOCOL, type MetricsCollector, type MetricsSnapshot, type NamedTransport, type NegotiateOptions, type NegotiationOutcome, type NegotiationReason, type NegotiationResult, NonDeterminismError, type PayloadCodec, type QueueConfig, QueueController, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, type ScheduledWorkflow, type SearchAttributes, type SearchAttributesSchema, SignalTimeoutError, type SignalWaiter, type SingletonConfig, SingletonQueueFullError, 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 StepUndo, type StoreTransaction, type SubProcessHandle, TERMINAL_RUN_STATUSES, TRANSPORT, TRANSPORT_CANONICAL, type TenantEvent, type Transport, type UndoOf, type UpdateResult, type UpdateValidator, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, WorkflowBlocked, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, applyAttributeQuery, attributeColumnFor, attributeOperand, bindWorkflowClass, breakpointToken, canRoute, capableWorkers, classifyWaiterToken, collectMetrics, controlPlaneDescriptor, createStepLogger, currentWorkflowCtx, descriptorHash, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, heartbeatStatus, indexWaitersByRun, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, matchesAttributes, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, parseDuration, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, tenantGroup, workflowName };
|