@dudousxd/nestjs-durable-core 0.77.0 → 0.79.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 +1200 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +590 -120
- package/dist/index.d.ts +590 -120
- package/dist/index.js +1170 -84
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -195,6 +195,16 @@ interface WorkflowRegistration {
|
|
|
195
195
|
/** The package that DECLARED the workflow (see `WorkflowRun.origin`). Absent = unknown; nothing
|
|
196
196
|
* ever substitutes a default, because a wrong origin is worse than no origin. */
|
|
197
197
|
origin?: string;
|
|
198
|
+
/**
|
|
199
|
+
* Where the engine routes a failed run of this workflow, by error `code` (`code` absent = the
|
|
200
|
+
* catch-all): the handler workflow it starts instead of failing the run. The one announced field
|
|
201
|
+
* the engine ACTS on, for a workflow it serves by convention rather than by local registration.
|
|
202
|
+
* Absent = not stated, which routes nothing.
|
|
203
|
+
*/
|
|
204
|
+
onError?: {
|
|
205
|
+
code?: string;
|
|
206
|
+
workflow: string;
|
|
207
|
+
}[];
|
|
198
208
|
}
|
|
199
209
|
/**
|
|
200
210
|
* A worker's (or control-plane's) advertised identity, wire-protocol support, feature capabilities
|
|
@@ -474,6 +484,230 @@ declare class WorkflowBlocked extends Error {
|
|
|
474
484
|
*/
|
|
475
485
|
declare function planDispatch(requires: string[], liveDescriptors: readonly (RawWorkerDescriptor | WorkerDescriptor)[], cp: WorkerDescriptor, token: string): DispatchPlan;
|
|
476
486
|
|
|
487
|
+
/**
|
|
488
|
+
* A parallel fan (a `ctx.all`, a step fan, a polyglot `gather`) reduced to what a detail view needs
|
|
489
|
+
* to draw it: one node, its progress and its failures. A run detail with a 40,000-item fan otherwise
|
|
490
|
+
* carries every member — megabytes of JSON, and one rendered row (or fetched child) per member.
|
|
491
|
+
*/
|
|
492
|
+
interface FanSummary {
|
|
493
|
+
/** The fan's `parallelGroup`. */
|
|
494
|
+
group: string;
|
|
495
|
+
/** The members' common step name, or `child runs` for a fan of child workflows. */
|
|
496
|
+
label: string;
|
|
497
|
+
firstSeq: number;
|
|
498
|
+
lastSeq: number;
|
|
499
|
+
/** Members started so far: steps, or child runs (a folded checkpoint counts as the children it stands for). */
|
|
500
|
+
size: number;
|
|
501
|
+
/**
|
|
502
|
+
* The fan's declared size, when its group carries it. More than `size` while waves are still to
|
|
503
|
+
* be sent (`concurrency`), and for good when a failFast fan stopped early.
|
|
504
|
+
*/
|
|
505
|
+
total?: number | undefined;
|
|
506
|
+
/** `total - size`: members never started yet — or never to start, once the run has finished. */
|
|
507
|
+
notStarted?: number | undefined;
|
|
508
|
+
/** The fan stops at its first failure. */
|
|
509
|
+
failFast: boolean;
|
|
510
|
+
/** Members by status. A child that failed counts as `failed`, though its checkpoint is `completed`. */
|
|
511
|
+
counts: Partial<Record<StepCheckpoint['status'], number>>;
|
|
512
|
+
startedAt?: Date | undefined;
|
|
513
|
+
finishedAt?: Date | undefined;
|
|
514
|
+
/** The first {@link FAN_SUMMARY_FAILURES} failed members, so a failure shows without paging. */
|
|
515
|
+
failures: StepCheckpoint[];
|
|
516
|
+
}
|
|
517
|
+
/** A page of one fan's members, in seq order. */
|
|
518
|
+
interface FanPage {
|
|
519
|
+
items: StepCheckpoint[];
|
|
520
|
+
/** Members matching the query, across all pages. */
|
|
521
|
+
total: number;
|
|
522
|
+
/** A validator for this page, when the gateway can compute one without reading the members. */
|
|
523
|
+
etag?: string | undefined;
|
|
524
|
+
/**
|
|
525
|
+
* Set when the query's `ifNoneMatch` matched {@link etag}: the page has not changed, so nothing
|
|
526
|
+
* was read. `items` is empty and `total` is 0 as placeholders, not the fan's; keep the page the
|
|
527
|
+
* caller already holds.
|
|
528
|
+
*/
|
|
529
|
+
notModified?: true | undefined;
|
|
530
|
+
}
|
|
531
|
+
interface FanPageQuery {
|
|
532
|
+
offset?: number | undefined;
|
|
533
|
+
limit?: number | undefined;
|
|
534
|
+
/** Only failed members (a failed step, or a child that failed). */
|
|
535
|
+
failedOnly?: boolean | undefined;
|
|
536
|
+
/** An HTTP `If-None-Match` value: a page whose `etag` it names comes back `notModified`. */
|
|
537
|
+
ifNoneMatch?: string | undefined;
|
|
538
|
+
}
|
|
539
|
+
declare const FAN_SUMMARY_FAILURES = 20;
|
|
540
|
+
/** The most children a summarized detail lists by id; `childCount` carries the rest. */
|
|
541
|
+
declare const SUMMARY_CHILD_LIMIT = 200;
|
|
542
|
+
/** How many children a folded `fan:` checkpoint stands for; undefined for any other checkpoint. */
|
|
543
|
+
declare function foldedCount(cp: StepCheckpoint): number | undefined;
|
|
544
|
+
/** A failed member: a failed step, or a child whose completion reports `ok: false`. */
|
|
545
|
+
declare function isFailedMember(cp: StepCheckpoint): boolean;
|
|
546
|
+
/** Summarize one fan's members (in seq order). */
|
|
547
|
+
declare function summarizeFan(group: string, members: StepCheckpoint[]): FanSummary;
|
|
548
|
+
/**
|
|
549
|
+
* Split a run's timeline into the checkpoints a detail view lists one by one and the fans it draws as
|
|
550
|
+
* one node each: every `parallelGroup` with more than `over` members, or declared wider than that,
|
|
551
|
+
* becomes a {@link FanSummary}, and its members leave the timeline. Smaller groups and ungrouped steps stay as they are.
|
|
552
|
+
*/
|
|
553
|
+
declare function summarizeTimeline(timeline: StepCheckpoint[], over: number): {
|
|
554
|
+
timeline: StepCheckpoint[];
|
|
555
|
+
fans: FanSummary[];
|
|
556
|
+
};
|
|
557
|
+
/** One page of a fan's members out of a run's timeline. */
|
|
558
|
+
declare function pageFan(timeline: StepCheckpoint[], group: string, query: FanPageQuery): FanPage;
|
|
559
|
+
/** A {@link FanPageQuery}'s offset and limit, clamped to sane bounds. */
|
|
560
|
+
declare function fanPageBounds(query: FanPageQuery): {
|
|
561
|
+
offset: number;
|
|
562
|
+
limit: number;
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
/** A run as returned by the gateway's list — the durable run plus an optional {@link RunWaiting}
|
|
566
|
+
* descriptor the control plane resolves (what a suspended run is parked on), so the dashboard can
|
|
567
|
+
* name the wait in a list row without fetching each run's timeline. Additive: `waiting` is absent
|
|
568
|
+
* on a non-parked run and on gateways/versions that don't compute it. */
|
|
569
|
+
type RunListItem = WorkflowRun & {
|
|
570
|
+
waiting?: RunWaiting | undefined;
|
|
571
|
+
};
|
|
572
|
+
/** Which durable topology a gateway speaks for — surfaced in the dashboard so an operator can tell a
|
|
573
|
+
* control plane from a tenant at a glance (the store-backed gateway is the operator; the proxy is a
|
|
574
|
+
* tenant). Cheap, synchronous, local knowledge — no round-trip. */
|
|
575
|
+
interface DurableTopology {
|
|
576
|
+
role: 'control-plane' | 'tenant';
|
|
577
|
+
/** The tenant's isolation partition name; set only when `role` is 'tenant'. */
|
|
578
|
+
tenant?: string;
|
|
579
|
+
}
|
|
580
|
+
/** A run + its timeline + child ids — the detail view. Single source of truth: the dashboard server
|
|
581
|
+
* re-exports this instead of re-declaring it, and the dashboard client derives its wire mirror from
|
|
582
|
+
* it via {@link WireDates} instead of hand-mirroring field by field. */
|
|
583
|
+
interface RunDetail {
|
|
584
|
+
run: WorkflowRun;
|
|
585
|
+
/**
|
|
586
|
+
* Steps in execution order (local + remote). With {@link RunDetailOptions.summarizeFansOver}, the
|
|
587
|
+
* members of a summarized fan are left out — see {@link fans}.
|
|
588
|
+
*/
|
|
589
|
+
timeline: StepCheckpoint[];
|
|
590
|
+
/** Ids of runs this run spawned (parent→children tree). Capped when summarized — see {@link childCount}. */
|
|
591
|
+
children: string[];
|
|
592
|
+
/** The fans drawn as one node each, when the detail was asked to summarize them. */
|
|
593
|
+
fans?: FanSummary[] | undefined;
|
|
594
|
+
/** How many children the run has, when `children` lists only the first of them. */
|
|
595
|
+
childCount?: number | undefined;
|
|
596
|
+
/**
|
|
597
|
+
* A validator for this detail, when the gateway can compute one without reading the timeline:
|
|
598
|
+
* it changes whenever the run or any of its checkpoints does. Absent when it cannot.
|
|
599
|
+
*/
|
|
600
|
+
etag?: string | undefined;
|
|
601
|
+
/**
|
|
602
|
+
* Set when {@link RunDetailOptions.ifNoneMatch} matched {@link etag}: nothing changed, so only
|
|
603
|
+
* `run` was read — `timeline` and `children` are empty, not the run's.
|
|
604
|
+
*/
|
|
605
|
+
notModified?: true | undefined;
|
|
606
|
+
}
|
|
607
|
+
/** How to shape a {@link RunDetail}. */
|
|
608
|
+
interface RunDetailOptions {
|
|
609
|
+
/**
|
|
610
|
+
* Summarize every fan with more than this many members into a {@link FanSummary} instead of
|
|
611
|
+
* listing them, and cap `children`. Unset returns the full timeline, as before. A view of a run
|
|
612
|
+
* with a wide fan should set it: the full detail of a 40k-member fan is megabytes.
|
|
613
|
+
*/
|
|
614
|
+
summarizeFansOver?: number | undefined;
|
|
615
|
+
/**
|
|
616
|
+
* An HTTP `If-None-Match` value. When it names the detail's current {@link RunDetail.etag}, the
|
|
617
|
+
* gateway answers `notModified` without reading the timeline. A gateway that cannot tell ignores it.
|
|
618
|
+
*/
|
|
619
|
+
ifNoneMatch?: string | undefined;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Maps every `Date` (and `Date | undefined`) field of `T` to its ISO-string wire form — the shape a
|
|
623
|
+
* JSON response actually carries once dates cross the wire (`JSON.stringify` already does this
|
|
624
|
+
* coercion; this just types it). Homomorphic: each field keeps its own optional modifier, so a
|
|
625
|
+
* required `Date` becomes a required `string` and an optional one stays optional. Lets a consumer
|
|
626
|
+
* derive its own wire-facing client type from a core server type (e.g. the dashboard's SPA `WorkflowRun`/
|
|
627
|
+
* `StepCheckpoint`/`RunDetail`) instead of hand-mirroring it field by field and drifting.
|
|
628
|
+
*/
|
|
629
|
+
type WireDates<T> = {
|
|
630
|
+
[K in keyof T]: T[K] extends Date ? string : T[K] extends Date | undefined ? string | undefined : T[K];
|
|
631
|
+
};
|
|
632
|
+
/**
|
|
633
|
+
* The bounded read/control/stream surface a consumer (e.g. a controller) needs, satisfied by BOTH
|
|
634
|
+
* topologies: the control plane binds a store-backed impl (reuses `DashboardService`); a tenant binds
|
|
635
|
+
* a `ProxyRunGateway` that round-trips over the transport. Deliberately smaller than the full dashboard
|
|
636
|
+
* (no metrics/bulk/update/signal) — those stay control-plane-only. `workerHealth` IS on the port: the
|
|
637
|
+
* operator answers it scoped to the requester's own groups, so a tenant's Workers panel works too.
|
|
638
|
+
*
|
|
639
|
+
* Declared as an **abstract class** rather than an interface so it doubles as its own NestJS DI token
|
|
640
|
+
* (the idiomatic inject-by-type pattern): providers bind `{ provide: RunGateway, useClass/useFactory }`
|
|
641
|
+
* and consumers inject `constructor(private readonly gateway: RunGateway)` with no string/symbol token.
|
|
642
|
+
* `StoreRunGateway`/`ProxyRunGateway` `implements RunGateway`; abstract methods carry no body, so the
|
|
643
|
+
* emitted runtime class is an empty, non-instantiable shell used only as the token.
|
|
644
|
+
*/
|
|
645
|
+
declare abstract class RunGateway {
|
|
646
|
+
/** This deployment's durable role (control plane vs tenant) — synchronous local metadata. */
|
|
647
|
+
abstract topology(): DurableTopology;
|
|
648
|
+
abstract getRunDetail(runId: string, options?: RunDetailOptions): Promise<RunDetail | null>;
|
|
649
|
+
/**
|
|
650
|
+
* One page of a fan's members, for a view that drew the fan from its {@link FanSummary}. Optional:
|
|
651
|
+
* a gateway without it serves summarized details whose fans cannot be expanded.
|
|
652
|
+
*/
|
|
653
|
+
getFanMembers?(runId: string, group: string, query: FanPageQuery): Promise<FanPage | null>;
|
|
654
|
+
/**
|
|
655
|
+
* The run alone, without its timeline. Optional: a caller that only needs the run (an ownership
|
|
656
|
+
* check) falls back to {@link getRunDetail}, which reads every checkpoint.
|
|
657
|
+
*/
|
|
658
|
+
getRun?(runId: string): Promise<WorkflowRun | null>;
|
|
659
|
+
/** List runs, each optionally carrying a {@link RunWaiting} descriptor (what a suspended run is
|
|
660
|
+
* parked on). The store-backed gateway resolves `waiting`; a proxy relays whatever the control
|
|
661
|
+
* plane sent. */
|
|
662
|
+
abstract listRuns(query: RunQuery): Promise<RunListItem[]>;
|
|
663
|
+
/**
|
|
664
|
+
* Counts of the runs matching `query`, grouped by `(status, origin)` — what a console's status and
|
|
665
|
+
* origin chips display. Separate from {@link listRuns} precisely so the list can be PAGINATED: the
|
|
666
|
+
* page bounds what is rendered, these counts stay whole-set exact. Zero-count cells are absent.
|
|
667
|
+
*/
|
|
668
|
+
abstract runFacets(query: RunFacetQuery): Promise<RunFacetRow[]>;
|
|
669
|
+
/**
|
|
670
|
+
* The distinct values of one filter axis over the runs matching `query`, with counts — what fills a
|
|
671
|
+
* console's tenant/tag/attribute pickers. On the port (not control-plane-only) because the pickers
|
|
672
|
+
* belong to the same panel as {@link listRuns}: a tenant that can list its runs has to be able to
|
|
673
|
+
* see what it may filter them by, or its console offers a blank dropdown.
|
|
674
|
+
*
|
|
675
|
+
* Returns `[]` when the underlying store does not implement the enumeration — an empty picker with
|
|
676
|
+
* free-text entry still standing, not an error.
|
|
677
|
+
*/
|
|
678
|
+
abstract runValueFacets(axis: RunValueAxis, query: RunFacetQuery, opts?: RunValueFacetOptions): Promise<RunValueFacetRow[]>;
|
|
679
|
+
/**
|
|
680
|
+
* Bulk-resolve {@link RunWaiting} for an arbitrary set of run ids — for a consumer with its OWN
|
|
681
|
+
* filtered/paginated run listing (so it isn't just `listRuns` under another name) that needs to know
|
|
682
|
+
* which of ITS runs are parked on a breakpoint (or any other event wait) without re-deriving the bulk
|
|
683
|
+
* waiter scan itself or reaching for raw SQL against `durable_step_checkpoints`. A `Record` (not a
|
|
684
|
+
* `Map`) because `ProxyRunGateway` serialises the reply over the transport as plain JSON. Entries are
|
|
685
|
+
* present ONLY for runs currently waiting — an unknown id, a non-suspended id, and a suspended id
|
|
686
|
+
* parked on something non-event (a bare `ctx.sleep`, an in-flight step) are simply absent, same as a
|
|
687
|
+
* `listRuns` row with no `waiting`.
|
|
688
|
+
*/
|
|
689
|
+
abstract waitingFor(runIds: string[]): Promise<Record<string, RunWaiting>>;
|
|
690
|
+
/** Per-group worker health (queue backlog + live worker heartbeats). On the control plane this is
|
|
691
|
+
* every group; over a tenant proxy the operator scopes it to the tenant's own groups. */
|
|
692
|
+
abstract workerHealth(): Promise<GroupHealth[]>;
|
|
693
|
+
abstract cancel(runId: string, opts?: {
|
|
694
|
+
compensate?: boolean;
|
|
695
|
+
}): Promise<RunResult | null>;
|
|
696
|
+
abstract retry(runId: string): Promise<RunResult | null>;
|
|
697
|
+
abstract continue(runId: string): Promise<RunResult | null>;
|
|
698
|
+
/** Re-dispatch every remote step of a run stuck `pending` — the operator recovery for a LOST step
|
|
699
|
+
* dispatch (crashed worker / dropped job) that no automatic path re-drives. Returns the run's status
|
|
700
|
+
* plus how many steps were re-dispatched, or null if the run is unknown. */
|
|
701
|
+
abstract redispatchPending(runId: string): Promise<(RunResult & {
|
|
702
|
+
redispatched: number;
|
|
703
|
+
}) | null>;
|
|
704
|
+
abstract retryWithInput(runId: string, input: unknown): Promise<{
|
|
705
|
+
runId: string;
|
|
706
|
+
} | null>;
|
|
707
|
+
/** Live lifecycle events for one run; returns an unsubscribe fn. Framework-agnostic (no rxjs). */
|
|
708
|
+
abstract subscribe(runId: string, onEvent: (event: EngineEvent) => void): () => void;
|
|
709
|
+
}
|
|
710
|
+
|
|
477
711
|
/**
|
|
478
712
|
* Vendored subset of the Standard Schema spec (https://standardschema.dev) — the `~standard`
|
|
479
713
|
* property protocol implemented by zod 3.24+, valibot, arktype, and others. Vendored (rather than
|
|
@@ -909,6 +1143,9 @@ interface StepError {
|
|
|
909
1143
|
message: string;
|
|
910
1144
|
/** Optional machine-readable code, e.g. `declined`, `timeout`. */
|
|
911
1145
|
code?: string | undefined;
|
|
1146
|
+
/** Structured, JSON-serializable detail of the failure (e.g. validation issues), from
|
|
1147
|
+
* `FatalError`'s third argument or a `details` on what a step handler threw. */
|
|
1148
|
+
details?: unknown;
|
|
912
1149
|
/** Whether the engine should treat this as retryable. */
|
|
913
1150
|
retryable?: boolean | undefined;
|
|
914
1151
|
stack?: string | undefined;
|
|
@@ -979,6 +1216,16 @@ interface StateStore {
|
|
|
979
1216
|
* Optional: a store that omits it falls back to {@link saveCheckpoint}, which keeps that race.
|
|
980
1217
|
*/
|
|
981
1218
|
saveCheckpointIfPending?(checkpoint: StepCheckpoint): Promise<boolean>;
|
|
1219
|
+
/**
|
|
1220
|
+
* {@link saveCheckpointIfPending} for many checkpoints in one call: resolves, per entry and in
|
|
1221
|
+
* input order, whether it wrote. Same result as calling it on each entry in turn (a later entry for
|
|
1222
|
+
* the same `(runId, seq)` is compared against the earlier one's write), with each row's
|
|
1223
|
+
* compare-and-set still atomic. The call as a whole is atomic too: if it rejects, nothing was
|
|
1224
|
+
* written. The engine settles a batch of one run's step results through it, one call per batch.
|
|
1225
|
+
*
|
|
1226
|
+
* Optional: a store that omits it gets one {@link saveCheckpointIfPending} per entry.
|
|
1227
|
+
*/
|
|
1228
|
+
saveCheckpointsIfPending?(checkpoints: StepCheckpoint[]): Promise<boolean[]>;
|
|
982
1229
|
/** Used by recovery on boot to find runs to resume (crashed, left `running`). */
|
|
983
1230
|
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
984
1231
|
/** The oldest `pending` runs awaiting dispatch (FIFO, by `createdAt`), capped at `limit`. */
|
|
@@ -1188,6 +1435,72 @@ interface StateStore {
|
|
|
1188
1435
|
* and counts in JS, which loads the whole run on every result of a fan.
|
|
1189
1436
|
*/
|
|
1190
1437
|
countCheckpoints?(runId: string, fromSeq: number, toSeq: number, statuses: StepCheckpoint['status'][]): Promise<number>;
|
|
1438
|
+
/**
|
|
1439
|
+
* The run's checkpoints aggregated into {@link CheckpointStat} buckets — one per
|
|
1440
|
+
* `(parallelGroup, status, nameKind)` present — with `opts.group` narrowing it to one group. A
|
|
1441
|
+
* `GROUP BY`, not a load: it is what lets a run detail draw a 40,000-member fan from a few rows.
|
|
1442
|
+
* Ungrouped checkpoints come back under `group: null`. Bucket order is unspecified.
|
|
1443
|
+
*
|
|
1444
|
+
* Optional: a store that omits it still works — the console's run detail then loads every
|
|
1445
|
+
* checkpoint and summarizes it in JS (`summarizeTimeline`), which is the same answer read the
|
|
1446
|
+
* expensive way. A store that implements it must implement {@link queryCheckpoints} too.
|
|
1447
|
+
*/
|
|
1448
|
+
checkpointStats?(runId: string, opts?: {
|
|
1449
|
+
group?: string | undefined;
|
|
1450
|
+
}): Promise<CheckpointStat[]>;
|
|
1451
|
+
/**
|
|
1452
|
+
* The run's checkpoints that match `query`, in `seq` order (the order of {@link listCheckpoints}),
|
|
1453
|
+
* paged by `offset`/`limit`. Every filter is optional; an absent one does not narrow. An EMPTY
|
|
1454
|
+
* `statuses` or `namePrefixes` matches nothing; an empty `excludeGroups` excludes nothing.
|
|
1455
|
+
*
|
|
1456
|
+
* Optional, paired with {@link checkpointStats}: the run detail reads a fan's failures, its folded
|
|
1457
|
+
* checkpoints and one page of its members through it, instead of the run's whole history.
|
|
1458
|
+
*/
|
|
1459
|
+
queryCheckpoints?(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]>;
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* How a checkpoint's name classifies it, for {@link CheckpointStat}: an awaited child's
|
|
1463
|
+
* `signal:child:` checkpoint, a folded `fan:` checkpoint standing for many children, a `spawn:`
|
|
1464
|
+
* edge to a fire-and-forget child, or any other step.
|
|
1465
|
+
*/
|
|
1466
|
+
type CheckpointNameKind = 'child' | 'folded' | 'spawn' | 'step';
|
|
1467
|
+
/** The {@link CheckpointNameKind} of a checkpoint name — what a store's SQL `CASE` must agree with. */
|
|
1468
|
+
declare function checkpointNameKind(name: string): CheckpointNameKind;
|
|
1469
|
+
/**
|
|
1470
|
+
* One bucket of {@link StateStore.checkpointStats}: the checkpoints of one run sharing a
|
|
1471
|
+
* `parallelGroup`, a `status` and a {@link CheckpointNameKind}, reduced to aggregates.
|
|
1472
|
+
*/
|
|
1473
|
+
interface CheckpointStat {
|
|
1474
|
+
/** The bucket's `parallelGroup`, or `null` for ungrouped checkpoints. */
|
|
1475
|
+
group: string | null;
|
|
1476
|
+
status: StepCheckpoint['status'];
|
|
1477
|
+
nameKind: CheckpointNameKind;
|
|
1478
|
+
/** Rows in the bucket (at least 1). */
|
|
1479
|
+
count: number;
|
|
1480
|
+
minSeq: number;
|
|
1481
|
+
maxSeq: number;
|
|
1482
|
+
/** Smallest and largest `name`, by the database's string order. Equal when every row shares one. */
|
|
1483
|
+
minName: string;
|
|
1484
|
+
maxName: string;
|
|
1485
|
+
/** Earliest `enqueuedAt`, read as {@link StateStore.listCheckpoints} reads it (falling back to `startedAt`). */
|
|
1486
|
+
minEnqueuedAt: Date;
|
|
1487
|
+
minStartedAt: Date;
|
|
1488
|
+
maxStartedAt: Date;
|
|
1489
|
+
maxFinishedAt: Date;
|
|
1490
|
+
/** Sum of `attempts` — moves when a step is retried in place, so a change marker sees it. */
|
|
1491
|
+
sumAttempts: number;
|
|
1492
|
+
}
|
|
1493
|
+
/** What {@link StateStore.queryCheckpoints} selects. */
|
|
1494
|
+
interface CheckpointQuery {
|
|
1495
|
+
/** Only this `parallelGroup`'s checkpoints. */
|
|
1496
|
+
group?: string | undefined;
|
|
1497
|
+
/** Leave out these groups' checkpoints (ungrouped checkpoints are kept). */
|
|
1498
|
+
excludeGroups?: string[] | undefined;
|
|
1499
|
+
statuses?: StepCheckpoint['status'][] | undefined;
|
|
1500
|
+
/** Only names starting with one of these. */
|
|
1501
|
+
namePrefixes?: string[] | undefined;
|
|
1502
|
+
offset?: number | undefined;
|
|
1503
|
+
limit?: number | undefined;
|
|
1191
1504
|
}
|
|
1192
1505
|
/**
|
|
1193
1506
|
* A persisted schedule as the STORE sees it: a handful of queryable columns plus two JSON documents
|
|
@@ -1513,6 +1826,26 @@ interface AllStepsOptions extends Omit<StepDispatchOpts, 'queue' | 'timeoutMs'>
|
|
|
1513
1826
|
*/
|
|
1514
1827
|
concurrency?: number;
|
|
1515
1828
|
}
|
|
1829
|
+
/** Options for {@link WorkflowCtx.allSettled} over child workflows: {@link AllOptions} without `mode`. */
|
|
1830
|
+
type AllSettledOptions = Omit<AllOptions, 'mode'>;
|
|
1831
|
+
/** Options for {@link WorkflowCtx.allSettled} over a `@Step`: {@link AllStepsOptions} without `mode`. */
|
|
1832
|
+
type AllStepsSettledOptions = Omit<AllStepsOptions, 'mode'>;
|
|
1833
|
+
/**
|
|
1834
|
+
* One item of a {@link WorkflowCtx.allSettled} fan, in input order. `id` is the child run id (child
|
|
1835
|
+
* fan) or the step id (step fan); `error` is the failure message the child or step settled with.
|
|
1836
|
+
*/
|
|
1837
|
+
type Settled<T> = {
|
|
1838
|
+
status: 'fulfilled';
|
|
1839
|
+
value: T;
|
|
1840
|
+
} | {
|
|
1841
|
+
status: 'rejected';
|
|
1842
|
+
id: string;
|
|
1843
|
+
error: string;
|
|
1844
|
+
/** The failure's `code` (e.g. a `FatalError`'s), so a parent can tell its kinds apart. */
|
|
1845
|
+
code?: string | undefined;
|
|
1846
|
+
/** The failure's structured `details`, when it carried any. */
|
|
1847
|
+
details?: unknown;
|
|
1848
|
+
};
|
|
1516
1849
|
/** One child of a fan as {@link StateStore.registerChildWaits} writes it. */
|
|
1517
1850
|
interface ChildWait {
|
|
1518
1851
|
waiter: SignalWaiter;
|
|
@@ -1569,6 +1902,12 @@ interface RunRequest {
|
|
|
1569
1902
|
type RunRequestKind = {
|
|
1570
1903
|
kind: 'getRunDetail';
|
|
1571
1904
|
runId: string;
|
|
1905
|
+
options?: RunDetailOptions | undefined;
|
|
1906
|
+
} | {
|
|
1907
|
+
kind: 'getFanMembers';
|
|
1908
|
+
runId: string;
|
|
1909
|
+
group: string;
|
|
1910
|
+
query: FanPageQuery;
|
|
1572
1911
|
} | {
|
|
1573
1912
|
kind: 'listRuns';
|
|
1574
1913
|
query: RunQuery;
|
|
@@ -2397,6 +2736,17 @@ interface WorkflowCtx<A extends SearchAttributes = SearchAttributes> {
|
|
|
2397
2736
|
*/
|
|
2398
2737
|
all<TInput, TOutput>(step: StepRef<TInput, TOutput>, inputs: TInput[], opts?: AllStepsOptions): Promise<TOutput[]>;
|
|
2399
2738
|
all<TOutput = unknown>(workflow: string, inputs: unknown[], opts?: AllOptions): Promise<TOutput[]>;
|
|
2739
|
+
/**
|
|
2740
|
+
* {@link all} that never throws for a failed item: waits for every child (or step) to settle, then
|
|
2741
|
+
* resolves with one {@link Settled} per input, in **input order** — the durable
|
|
2742
|
+
* `Promise.allSettled`. Same fan as `all` in `waitAll` mode (ids, `parallelGroup`, `concurrency`
|
|
2743
|
+
* waves, one parent turn per settled wave); only the ending differs. Use it when one item failing
|
|
2744
|
+
* is an expected outcome the parent handles (record it, dead-letter it) rather than a reason to
|
|
2745
|
+
* fail the whole run. Cancelling the parent still propagates.
|
|
2746
|
+
*/
|
|
2747
|
+
allSettled<C extends WorkflowClass>(workflow: C, inputs: WorkflowInputOf<C>[], opts?: AllSettledOptions): Promise<Settled<WorkflowOutputOf<C>>[]>;
|
|
2748
|
+
allSettled<TInput, TOutput>(step: StepRef<TInput, TOutput>, inputs: TInput[], opts?: AllStepsSettledOptions): Promise<Settled<TOutput>[]>;
|
|
2749
|
+
allSettled<TOutput = unknown>(workflow: string, inputs: unknown[], opts?: AllSettledOptions): Promise<Settled<TOutput>[]>;
|
|
2400
2750
|
/**
|
|
2401
2751
|
* Pause the run at this point until a human resumes it from the dashboard (or
|
|
2402
2752
|
* `engine.continue(runId)`). Records a visible `pending` checkpoint so the breakpoint shows up
|
|
@@ -2489,8 +2839,8 @@ interface WorkflowCtx<A extends SearchAttributes = SearchAttributes> {
|
|
|
2489
2839
|
localStep<TOutput>(name: string, fn: (log: StepLogger) => Promise<TOutput>, options?: StepOptions): Promise<TOutput>;
|
|
2490
2840
|
}
|
|
2491
2841
|
/**
|
|
2492
|
-
* {@link WorkflowCtx} with ONE signature per method: the string-addressed forms of the
|
|
2493
|
-
* methods (`step`, `child`, `startChild`, `all`), everything else unchanged.
|
|
2842
|
+
* {@link WorkflowCtx} with ONE signature per method: the string-addressed forms of the five overloaded
|
|
2843
|
+
* methods (`step`, `child`, `startChild`, `all`, `allSettled`), everything else unchanged.
|
|
2494
2844
|
*
|
|
2495
2845
|
* For code that drives the ctx DYNAMICALLY — an interpreter that runs a user-defined graph and only
|
|
2496
2846
|
* ever knows workflow/step names as strings — and for test fakes. An overloaded method is awkward to
|
|
@@ -2509,7 +2859,7 @@ interface WorkflowCtx<A extends SearchAttributes = SearchAttributes> {
|
|
|
2509
2859
|
* Every `WorkflowCtx<A>` is assignable to `DynamicWorkflowCtx<A>` (guarded by
|
|
2510
2860
|
* `dynamic-workflow-ctx.type-test.ts`), and a `Pick` of it is a plain object literal in a test.
|
|
2511
2861
|
*/
|
|
2512
|
-
interface DynamicWorkflowCtx<A extends SearchAttributes = SearchAttributes> extends Omit<WorkflowCtx<A>, 'step' | 'child' | 'startChild' | 'all'> {
|
|
2862
|
+
interface DynamicWorkflowCtx<A extends SearchAttributes = SearchAttributes> extends Omit<WorkflowCtx<A>, 'step' | 'child' | 'startChild' | 'all' | 'allSettled'> {
|
|
2513
2863
|
/** {@link WorkflowCtx.step} by step name (a cross-runtime handler, or a `@Step` by its name). */
|
|
2514
2864
|
step<TOutput = unknown, TInput = unknown>(name: string, input: TInput, opts?: StepDispatchOpts & {
|
|
2515
2865
|
compensate?: string;
|
|
@@ -2520,6 +2870,8 @@ interface DynamicWorkflowCtx<A extends SearchAttributes = SearchAttributes> exte
|
|
|
2520
2870
|
startChild(workflow: string, input: unknown, options?: string | ChildCallOptions): Promise<string>;
|
|
2521
2871
|
/** {@link WorkflowCtx.all} by workflow name. */
|
|
2522
2872
|
all<TOutput = unknown>(workflow: string, inputs: unknown[], opts?: AllOptions): Promise<TOutput[]>;
|
|
2873
|
+
/** {@link WorkflowCtx.allSettled} by workflow name. */
|
|
2874
|
+
allSettled<TOutput = unknown>(workflow: string, inputs: unknown[], opts?: AllSettledOptions): Promise<Settled<TOutput>[]>;
|
|
2523
2875
|
}
|
|
2524
2876
|
/** Result of executing or resuming a workflow run. */
|
|
2525
2877
|
interface RunResult {
|
|
@@ -2542,7 +2894,7 @@ type UpdateResult = {
|
|
|
2542
2894
|
accepted: true;
|
|
2543
2895
|
run: RunResult | null;
|
|
2544
2896
|
};
|
|
2545
|
-
type EngineEventType = 'run.started' | 'run.completed' | 'run.failed' | 'run.suspended' | 'step.started' | 'step.completed' | 'step.failed' | 'step.progress' | 'run.blocked';
|
|
2897
|
+
type EngineEventType = 'run.started' | 'run.completed' | 'run.failed' | 'run.suspended' | 'step.started' | 'step.completed' | 'step.failed' | 'step.progress' | 'run.blocked' | 'run.routed' | 'run.unrouted';
|
|
2546
2898
|
/**
|
|
2547
2899
|
* A lifecycle event emitted by the engine. The observability surfaces (dashboard, OTel, the
|
|
2548
2900
|
* Telescope integration) all subscribe to these rather than reaching into the store.
|
|
@@ -2582,6 +2934,8 @@ interface EngineEvent {
|
|
|
2582
2934
|
* gap fired, how many live workers were considered, and both descriptors — enough for the health
|
|
2583
2935
|
* panel/telescope to render the reason. Absent on all other event types. */
|
|
2584
2936
|
diagnostics?: DispatchDiagnostics | undefined;
|
|
2937
|
+
/** Why a `run.unrouted` run's onError routes were not applied. */
|
|
2938
|
+
reason?: string | undefined;
|
|
2585
2939
|
at: Date;
|
|
2586
2940
|
}
|
|
2587
2941
|
type EngineListener = (event: EngineEvent) => void;
|
|
@@ -2982,7 +3336,7 @@ interface WorkflowAnnouncement extends WorkflowRegistration {
|
|
|
2982
3336
|
/** An axis on which the live announcers of one workflow do not agree. `values` holds every distinct
|
|
2983
3337
|
* DECLARED value (sorted); an announcer that stated nothing on the axis contributes nothing. */
|
|
2984
3338
|
interface Disagreement {
|
|
2985
|
-
axis: 'group' | 'origin' | 'requires';
|
|
3339
|
+
axis: 'group' | 'origin' | 'requires' | 'onError';
|
|
2986
3340
|
values: string[];
|
|
2987
3341
|
}
|
|
2988
3342
|
/**
|
|
@@ -3018,6 +3372,12 @@ interface AnnouncedWorkflow {
|
|
|
3018
3372
|
/** Every distinct capability demand announced, each de-duplicated + sorted. Empty = nobody stated
|
|
3019
3373
|
* one. Two entries here means two workers demand different capabilities for the same version. */
|
|
3020
3374
|
requires: string[][];
|
|
3375
|
+
/** Every distinct set of `onError` routes announced, each in canonical order. Empty = nobody stated
|
|
3376
|
+
* one. Two entries here means the live workers route this workflow's failures differently. */
|
|
3377
|
+
onError: {
|
|
3378
|
+
code?: string;
|
|
3379
|
+
workflow: string;
|
|
3380
|
+
}[][];
|
|
3021
3381
|
/** Runtimes of the live announcers (sorted, de-duplicated). EMPTY on an `'observed'` entry: a
|
|
3022
3382
|
* heartbeat does not say what runtime wrote it, and the instance id's shape is a convention, not
|
|
3023
3383
|
* a statement, so it is not read as one. */
|
|
@@ -3331,6 +3691,64 @@ type RoutingResolution = RoutableResolution | BlockedResolution;
|
|
|
3331
3691
|
*/
|
|
3332
3692
|
declare function resolveRouting(handler: CapabilityRequirement, workers: readonly (RawWorkerDescriptor | WorkerDescriptor)[]): RoutingResolution;
|
|
3333
3693
|
|
|
3694
|
+
/**
|
|
3695
|
+
* Routes a failed run to a handler workflow instead of failing it: when a run of the workflow ends
|
|
3696
|
+
* `failed` with an error whose `code` matches (or with any error, for the route without a `code`), the
|
|
3697
|
+
* engine starts `workflow` with an {@link OnErrorInput} and the failed run waits for it. The run then
|
|
3698
|
+
* settles with the handler's outcome: its output on success, its error on failure.
|
|
3699
|
+
*/
|
|
3700
|
+
interface OnErrorRoute {
|
|
3701
|
+
/** The error `code` to route. Omitted: routes any failure no other route's `code` matches. */
|
|
3702
|
+
code?: string | undefined;
|
|
3703
|
+
/** The registered handler workflow's name. */
|
|
3704
|
+
workflow: string;
|
|
3705
|
+
}
|
|
3706
|
+
/** The input an {@link OnErrorRoute} handler workflow is started with. */
|
|
3707
|
+
interface OnErrorInput<TInput = unknown> {
|
|
3708
|
+
/** The run that failed; it completes with this handler's output. */
|
|
3709
|
+
runId: string;
|
|
3710
|
+
/** The failed run's workflow. */
|
|
3711
|
+
workflow: string;
|
|
3712
|
+
/** The failed run's input. */
|
|
3713
|
+
input: TInput;
|
|
3714
|
+
/** The failure, as the run recorded it. */
|
|
3715
|
+
error: StepError;
|
|
3716
|
+
}
|
|
3717
|
+
/**
|
|
3718
|
+
* Handoff checkpoints live at seqs from here up, one per handoff, so a body that runs again after a
|
|
3719
|
+
* retry can never reach one. Fits a 32-bit `seq` column.
|
|
3720
|
+
*/
|
|
3721
|
+
declare const HANDOFF_SEQ_BASE = 1000000000;
|
|
3722
|
+
/** The id of the handler run of a run's `attempt`-th handoff. */
|
|
3723
|
+
declare const onErrorRunId: (runId: string, attempt: number) => string;
|
|
3724
|
+
/** The waiter checkpoint a run waits on its handler under; renamed {@link retiredHandoffName} on retry. */
|
|
3725
|
+
declare const handoffName: (handlerId: string) => string;
|
|
3726
|
+
/** What a retry renames a handoff checkpoint to: kept in the timeline, never followed again. */
|
|
3727
|
+
declare const retiredHandoffName: (handlerId: string) => string;
|
|
3728
|
+
/** The handler run id a live handoff checkpoint of `runId` names, or undefined for any other one. */
|
|
3729
|
+
declare function handoffHandlerId(runId: string, cp: {
|
|
3730
|
+
seq: number;
|
|
3731
|
+
name: string;
|
|
3732
|
+
}): string | undefined;
|
|
3733
|
+
/** The run's live handoff (its latest, unretired one), if it handed a failure off. */
|
|
3734
|
+
declare function liveHandoff<C extends {
|
|
3735
|
+
seq: number;
|
|
3736
|
+
name: string;
|
|
3737
|
+
}>(runId: string, checkpoints: readonly C[]): C | undefined;
|
|
3738
|
+
/** The route a failure takes: the one for its exact code, else the catch-all, else none. */
|
|
3739
|
+
declare function routeFor(routes: OnErrorRoute[] | undefined, error: StepError): OnErrorRoute | undefined;
|
|
3740
|
+
/** Reject two routes for one code, or two catch-alls — ambiguous config, caught at registration. */
|
|
3741
|
+
declare function assertRoutes(workflow: string, routes: OnErrorRoute[]): void;
|
|
3742
|
+
/** The `code` carried by a thrown value: its own, a dispatched step's, or a thin-worker step's. */
|
|
3743
|
+
declare function codeOf(err: unknown): string | undefined;
|
|
3744
|
+
/** The `details` carried by a thrown value, from the same places as {@link codeOf}. */
|
|
3745
|
+
declare function detailsOf(err: unknown): unknown;
|
|
3746
|
+
/** `code` and `details` as optional keys, so an absent one is not written as `undefined`. */
|
|
3747
|
+
declare function codeAndDetails(err: unknown): {
|
|
3748
|
+
code?: string;
|
|
3749
|
+
details?: unknown;
|
|
3750
|
+
};
|
|
3751
|
+
|
|
3334
3752
|
/**
|
|
3335
3753
|
* A schedule definition — what `engine.schedules.create/upsert` take. Temporal-style: a persisted,
|
|
3336
3754
|
* runtime-managed recurring start of `workflow` with `input`, fired by every driving engine's timer
|
|
@@ -3844,6 +4262,8 @@ declare class WorkflowEngine {
|
|
|
3844
4262
|
private readonly updateValidators;
|
|
3845
4263
|
/** Runs being cancelled WITH saga compensation — see `cancel({ compensate: true })`. */
|
|
3846
4264
|
private readonly cancelRequested;
|
|
4265
|
+
/** {@link announcedRoutes} reads, by group + workflow + version. */
|
|
4266
|
+
private readonly announcedRoutesCache;
|
|
3847
4267
|
/**
|
|
3848
4268
|
* Seqs of the dispatched remote steps a turn suspended on, by run, while that turn executes on
|
|
3849
4269
|
* THIS instance — so the turn can re-check them once its lease is released (see
|
|
@@ -3865,6 +4285,8 @@ declare class WorkflowEngine {
|
|
|
3865
4285
|
private readonly stepFansFiredHere;
|
|
3866
4286
|
/** The tail of each run's queue of results being handled on this instance — see {@link serializedPerRun}. */
|
|
3867
4287
|
private readonly resultChains;
|
|
4288
|
+
/** Each run's results waiting to be settled on this instance — see {@link completeRemoteResult}. */
|
|
4289
|
+
private readonly resultQueues;
|
|
3868
4290
|
/** Flow-control admission backend for remote steps (see {@link registerQueue}). */
|
|
3869
4291
|
private readonly admission;
|
|
3870
4292
|
/** Runs on THIS instance blocked on admission, by queue — woken early on a freed-slot signal. */
|
|
@@ -3939,6 +4361,8 @@ declare class WorkflowEngine {
|
|
|
3939
4361
|
* when it cannot be derived with confidence: absent means UNKNOWN, and an absent origin is far
|
|
3940
4362
|
* cheaper to live with than a wrong one. */
|
|
3941
4363
|
origin?: string | undefined;
|
|
4364
|
+
/** Handler workflows a matching failure is routed to — see {@link OnErrorRoute}. */
|
|
4365
|
+
onError?: OnErrorRoute[] | undefined;
|
|
3942
4366
|
}): void;
|
|
3943
4367
|
/**
|
|
3944
4368
|
* The retained in-process body for `name@version`, for an IN-APP worker that consumes this engine's
|
|
@@ -3968,6 +4392,8 @@ declare class WorkflowEngine {
|
|
|
3968
4392
|
validateInput?: (input: unknown) => void | Promise<void>;
|
|
3969
4393
|
/** Capabilities a live worker must advertise to run this remote workflow's turns (handshake §7.5). */
|
|
3970
4394
|
requires?: string[];
|
|
4395
|
+
/** Handler workflows a matching failure is routed to — see {@link OnErrorRoute}. */
|
|
4396
|
+
onError?: OnErrorRoute[];
|
|
3971
4397
|
}): void;
|
|
3972
4398
|
/**
|
|
3973
4399
|
* The convenience form of {@link registerRemote}: register a workflow whose body runs on a worker
|
|
@@ -3994,6 +4420,8 @@ declare class WorkflowEngine {
|
|
|
3994
4420
|
validateInput?: (input: unknown) => void | Promise<void>;
|
|
3995
4421
|
/** Capabilities a live worker must advertise to run this workflow's turns (handshake §7.5). */
|
|
3996
4422
|
requires?: string[];
|
|
4423
|
+
/** Handler workflows a matching failure is routed to — see {@link OnErrorRoute}. */
|
|
4424
|
+
onError?: OnErrorRoute[];
|
|
3997
4425
|
}): void;
|
|
3998
4426
|
/**
|
|
3999
4427
|
* Register a flow-control queue referenced by `ctx.step(step, input, { queue })`. Caps concurrent
|
|
@@ -4644,6 +5072,47 @@ declare class WorkflowEngine {
|
|
|
4644
5072
|
* {@link runExecution}'s settle/suspend; the lease is held by {@link execute}. The result that lands
|
|
4645
5073
|
* us back here (a remote step finished, a timer fired) goes through `resume` like any TS workflow.
|
|
4646
5074
|
*/
|
|
5075
|
+
/**
|
|
5076
|
+
* The registered onError routes whose handler workflow nothing can run: not registered on this
|
|
5077
|
+
* engine, and no live worker group serves it. Meant for a boot-time warning: a typo in a handler's
|
|
5078
|
+
* name would otherwise surface only when the first run fails.
|
|
5079
|
+
*/
|
|
5080
|
+
unservedOnErrorRoutes(): Promise<{
|
|
5081
|
+
workflow: string;
|
|
5082
|
+
route: OnErrorRoute;
|
|
5083
|
+
}[]>;
|
|
5084
|
+
/** Validate a workflow's {@link OnErrorRoute}s at registration. */
|
|
5085
|
+
private checkedRoutes;
|
|
5086
|
+
/**
|
|
5087
|
+
* Route a failed run to its {@link OnErrorRoute} handler, read from the workflow's local registration
|
|
5088
|
+
* or, for one served by convention, from what its live workers announce. Starts the handler run and
|
|
5089
|
+
* waits for it the way a parent waits for a `ctx.child`: a `child:<handlerId>` waiter plus a
|
|
5090
|
+
* `running` placeholder checkpoint carrying the handler's name and input, so the handler's terminal
|
|
5091
|
+
* state wakes the run (buffered and reconciled like any child). From then on every execution of the
|
|
5092
|
+
* run only follows the handler ({@link followHandoff}); the body never runs again. Undefined when no
|
|
5093
|
+
* route matches: the run fails as usual.
|
|
5094
|
+
*
|
|
5095
|
+
* The placeholder sits past every seq the body used and is left out of {@link remoteHistory}.
|
|
5096
|
+
*/
|
|
5097
|
+
private routeFailure;
|
|
5098
|
+
/** A run's handoff checkpoints, live and retired: the only ones at {@link HANDOFF_SEQ_BASE} and up. */
|
|
5099
|
+
private handoffCheckpoints;
|
|
5100
|
+
/**
|
|
5101
|
+
* Where a run that handed its failure off stands: the handler's outcome once it settled (from the
|
|
5102
|
+
* wake's checkpoint, or off the handler run when the wake never arrived), else still waiting. Starts
|
|
5103
|
+
* the handler if the turn that handed off crashed before its deferred start ran.
|
|
5104
|
+
*/
|
|
5105
|
+
private followHandoff;
|
|
5106
|
+
/**
|
|
5107
|
+
* The onError routes the live workers announce for a workflow the engine serves by convention: the
|
|
5108
|
+
* one set they agree on, or none when they state none or cannot be read. Workers that announce
|
|
5109
|
+
* different sets (a rollout in progress) route nothing, and the run's failure is reported as a
|
|
5110
|
+
* `run.unrouted` event. Announcers of another version of the workflow are ignored. The read is
|
|
5111
|
+
* cached for {@link ANNOUNCED_ROUTES_TTL_MS}, so a burst of failures costs one descriptor read.
|
|
5112
|
+
*/
|
|
5113
|
+
private announcedRoutes;
|
|
5114
|
+
/** Every distinct onError route set the live workers of `group` announce for the run's workflow. */
|
|
5115
|
+
private readAnnouncedRoutes;
|
|
4647
5116
|
/**
|
|
4648
5117
|
* Apply a terminal/suspended transition once: persist the new run status, emit the matching
|
|
4649
5118
|
* lifecycle event, and (on completion/failure) wake a waiting parent. Both the TS and remote
|
|
@@ -4929,6 +5398,13 @@ declare class WorkflowEngine {
|
|
|
4929
5398
|
private noteRecent;
|
|
4930
5399
|
/** {@link StateStore.saveCheckpointIfPending}, or a plain save on a store without it. */
|
|
4931
5400
|
private savePendingCheckpoint;
|
|
5401
|
+
/**
|
|
5402
|
+
* {@link savePendingCheckpoint} for checkpoints at distinct seqs of one run: one
|
|
5403
|
+
* {@link StateStore.saveCheckpointsIfPending} call when the store has it, else one write each.
|
|
5404
|
+
* Never rejects as a whole: a write that failed is reported as that entry's error, and the batch
|
|
5405
|
+
* call rejecting means it wrote nothing, so the entries are then written one by one.
|
|
5406
|
+
*/
|
|
5407
|
+
private savePendingCheckpoints;
|
|
4932
5408
|
/** Enqueue a remote step task to its worker group via the transport pool. Shared by the initial
|
|
4933
5409
|
* dispatch, the opt-in self-heal re-dispatch (see `remoteRedispatchMs`), and the explicit
|
|
4934
5410
|
* {@link redispatchPending}. Carries the current trace/context so a re-dispatch is traceable. */
|
|
@@ -4945,15 +5421,33 @@ declare class WorkflowEngine {
|
|
|
4945
5421
|
* result (the dispatching one may be gone), so the run is crash/scale-safe. Resolves whether the
|
|
4946
5422
|
* run should now be resumed: not for a duplicate or late delivery (the checkpoint isn't `pending`),
|
|
4947
5423
|
* a run already finished, or a step fan whose barrier is still closed.
|
|
5424
|
+
*
|
|
5425
|
+
* Results of one run are settled in batches: the first starts a batch, and the ones that arrive
|
|
5426
|
+
* while it is being written form the next. Under load a wide fan's results are written by one
|
|
5427
|
+
* {@link StateStore.saveCheckpointsIfPending} call per batch, and the fan's barrier is asked once
|
|
5428
|
+
* per batch, not once per result. A result resolves only once its own write has committed, so the
|
|
5429
|
+
* transport acknowledges nothing that is not durable yet.
|
|
4948
5430
|
*/
|
|
4949
5431
|
private completeRemoteResult;
|
|
5432
|
+
/** Settle `queue` (a run's queued results) batch by batch until it is empty, then retire it. */
|
|
5433
|
+
private drainResultQueue;
|
|
5434
|
+
/**
|
|
5435
|
+
* Settle a batch of one run's step results. At most one of them resolves `true` (resume the run):
|
|
5436
|
+
* that resume replays every write of the batch, so a second would only replay it again. A result
|
|
5437
|
+
* whose read or write failed resolves its error, and the transport redelivers just that one.
|
|
5438
|
+
*/
|
|
5439
|
+
private completeRemoteResults;
|
|
4950
5440
|
/**
|
|
4951
5441
|
* The join barrier of a step fan: a result for one of its steps resumes the parent only once no
|
|
4952
5442
|
* step of the fan is still `pending` (a settled wave), or on a failure (failFast surfaces it, and a
|
|
4953
5443
|
* retry needs the parent to schedule it). Without it every result would replay the whole parent,
|
|
4954
|
-
* which makes a fan of N steps cost O(N²) checkpoint reads.
|
|
5444
|
+
* which makes a fan of N steps cost O(N²) checkpoint reads. `barriers` holds the answer per fan
|
|
5445
|
+
* for the rest of a batch. A barrier that cannot be read counts as open: a spare resume replays and
|
|
5446
|
+
* re-suspends, a lost one strands the run.
|
|
4955
5447
|
*/
|
|
4956
5448
|
private stepFanStillRunning;
|
|
5449
|
+
/** How many steps of a step fan's seq range are still `pending`. */
|
|
5450
|
+
private stepFanPending;
|
|
4957
5451
|
/**
|
|
4958
5452
|
* Apply a remote workflow-turn {@link WorkflowDecision} durably — runs on WHATEVER instance receives
|
|
4959
5453
|
* it over the broker (the dispatching one may be gone, or a point-to-point broker handed it to a
|
|
@@ -5007,6 +5501,10 @@ declare class RemoteStepError extends Error {
|
|
|
5007
5501
|
readonly stepError?: StepError | undefined;
|
|
5008
5502
|
constructor(stepError?: StepError);
|
|
5009
5503
|
}
|
|
5504
|
+
/** Checkpoint names that record a parent→child edge: an awaited child, a folded group of them, a spawn. */
|
|
5505
|
+
declare const CHILD_EDGE_PREFIXES: string[];
|
|
5506
|
+
/** The child run ids a parent's {@link CHILD_EDGE_PREFIXES} checkpoints point at (others are skipped). */
|
|
5507
|
+
declare function childIdsOf(checkpoints: StepCheckpoint[]): string[];
|
|
5010
5508
|
|
|
5011
5509
|
/**
|
|
5012
5510
|
* What the class-first statics need from whoever registered the workflow class: the engine, or a
|
|
@@ -5088,7 +5586,12 @@ declare function parseDuration(duration: string | number): number;
|
|
|
5088
5586
|
*/
|
|
5089
5587
|
declare class FatalError extends Error {
|
|
5090
5588
|
readonly code?: string | undefined;
|
|
5091
|
-
|
|
5589
|
+
/** Structured, JSON-serializable detail (e.g. validation issues). It travels with the failure to
|
|
5590
|
+
* the run's error, a parent's `allSettled` item and an onError handler's input. */
|
|
5591
|
+
readonly details?: unknown;
|
|
5592
|
+
/** Read by the step result builders, so a dispatched step's retry policy honours it too. */
|
|
5593
|
+
readonly retryable = false;
|
|
5594
|
+
constructor(message: string, code?: string, details?: unknown);
|
|
5092
5595
|
}
|
|
5093
5596
|
/**
|
|
5094
5597
|
* Thrown by `start` when a run would exceed its concurrency quota: `active` runs sharing the quota
|
|
@@ -5166,6 +5669,8 @@ declare class RemoteWorkflowTimeout extends Error {
|
|
|
5166
5669
|
* breaking changes (old runs finish on the version they started on).
|
|
5167
5670
|
*/
|
|
5168
5671
|
declare class NonDeterminismError extends Error {
|
|
5672
|
+
/** Marks the failure as a broken deploy, which an `onError` route never takes. */
|
|
5673
|
+
readonly code = "non_determinism";
|
|
5169
5674
|
readonly runId: string;
|
|
5170
5675
|
readonly seq: number;
|
|
5171
5676
|
constructor(runId: string, seq: number, expected: string, recorded: string);
|
|
@@ -5196,17 +5701,17 @@ declare class NestedWorkflowCallError extends FatalError {
|
|
|
5196
5701
|
* and the failing ids — the wait-all/fail-fast counterpart to a single child's FatalError. Mirrors
|
|
5197
5702
|
* the Python SDK's `GatherFailed`.
|
|
5198
5703
|
*/
|
|
5704
|
+
/** One failed item of a fan: its input index, the child run or step id, and its failure. */
|
|
5705
|
+
interface GatherItemFailure {
|
|
5706
|
+
index: number;
|
|
5707
|
+
id: string;
|
|
5708
|
+
error: string;
|
|
5709
|
+
code?: string | undefined;
|
|
5710
|
+
details?: unknown;
|
|
5711
|
+
}
|
|
5199
5712
|
declare class GatherError extends Error {
|
|
5200
|
-
readonly failures:
|
|
5201
|
-
|
|
5202
|
-
id: string;
|
|
5203
|
-
error: string;
|
|
5204
|
-
}[];
|
|
5205
|
-
constructor(failures: {
|
|
5206
|
-
index: number;
|
|
5207
|
-
id: string;
|
|
5208
|
-
error: string;
|
|
5209
|
-
}[], total?: number);
|
|
5713
|
+
readonly failures: GatherItemFailure[];
|
|
5714
|
+
constructor(failures: GatherItemFailure[], total?: number);
|
|
5210
5715
|
}
|
|
5211
5716
|
declare class WorkflowSuspended extends Error {
|
|
5212
5717
|
/** Epoch ms to auto-resume (durable sleep), or undefined when waiting on an external signal. */
|
|
@@ -5437,110 +5942,48 @@ declare function mergeRunValueFacetRows(rows: readonly {
|
|
|
5437
5942
|
*/
|
|
5438
5943
|
declare function runValueFacetsFromRuns(runs: readonly WorkflowRun[], axis: RunValueAxis, opts?: RunValueFacetOptions): RunValueFacetRow[];
|
|
5439
5944
|
|
|
5440
|
-
/** A
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
* on a non-parked run and on gateways/versions that don't compute it. */
|
|
5444
|
-
type RunListItem = WorkflowRun & {
|
|
5445
|
-
waiting?: RunWaiting | undefined;
|
|
5446
|
-
};
|
|
5447
|
-
/** Which durable topology a gateway speaks for — surfaced in the dashboard so an operator can tell a
|
|
5448
|
-
* control plane from a tenant at a glance (the store-backed gateway is the operator; the proxy is a
|
|
5449
|
-
* tenant). Cheap, synchronous, local knowledge — no round-trip. */
|
|
5450
|
-
interface DurableTopology {
|
|
5451
|
-
role: 'control-plane' | 'tenant';
|
|
5452
|
-
/** The tenant's isolation partition name; set only when `role` is 'tenant'. */
|
|
5453
|
-
tenant?: string;
|
|
5454
|
-
}
|
|
5455
|
-
/** A run + its timeline + child ids — the detail view. Single source of truth: the dashboard server
|
|
5456
|
-
* re-exports this instead of re-declaring it, and the dashboard client derives its wire mirror from
|
|
5457
|
-
* it via {@link WireDates} instead of hand-mirroring field by field. */
|
|
5458
|
-
interface RunDetail {
|
|
5459
|
-
run: WorkflowRun;
|
|
5460
|
-
/** Steps in execution order (local + remote). */
|
|
5461
|
-
timeline: StepCheckpoint[];
|
|
5462
|
-
/** Ids of runs this run spawned (parent→children tree). */
|
|
5463
|
-
children: string[];
|
|
5464
|
-
}
|
|
5945
|
+
/** A store that aggregates checkpoints itself: both halves of the pair are present. */
|
|
5946
|
+
type CheckpointAggregatingStore = StateStore & Required<Pick<StateStore, 'checkpointStats' | 'queryCheckpoints'>>;
|
|
5947
|
+
declare function aggregatesCheckpoints(store: StateStore): store is CheckpointAggregatingStore;
|
|
5465
5948
|
/**
|
|
5466
|
-
*
|
|
5467
|
-
*
|
|
5468
|
-
* coercion; this just types it). Homomorphic: each field keeps its own optional modifier, so a
|
|
5469
|
-
* required `Date` becomes a required `string` and an optional one stays optional. Lets a consumer
|
|
5470
|
-
* derive its own wire-facing client type from a core server type (e.g. the dashboard's SPA `WorkflowRun`/
|
|
5471
|
-
* `StepCheckpoint`/`RunDetail`) instead of hand-mirroring it field by field and drifting.
|
|
5949
|
+
* {@link StateStore.checkpointStats} over checkpoints already in memory — the reference a store's
|
|
5950
|
+
* `GROUP BY` must agree with, and the in-memory store's implementation.
|
|
5472
5951
|
*/
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
};
|
|
5952
|
+
declare function checkpointStatsOf(checkpoints: StepCheckpoint[], opts?: {
|
|
5953
|
+
group?: string | undefined;
|
|
5954
|
+
}): CheckpointStat[];
|
|
5955
|
+
/** {@link StateStore.queryCheckpoints} over checkpoints already in memory, sorted by `seq` here. */
|
|
5956
|
+
declare function queryCheckpointsOf(checkpoints: StepCheckpoint[], query: CheckpointQuery): StepCheckpoint[];
|
|
5476
5957
|
/**
|
|
5477
|
-
*
|
|
5478
|
-
*
|
|
5479
|
-
*
|
|
5480
|
-
* (no metrics/bulk/update/signal) — those stay control-plane-only. `workerHealth` IS on the port: the
|
|
5481
|
-
* operator answers it scoped to the requester's own groups, so a tenant's Workers panel works too.
|
|
5958
|
+
* What `summarizeTimeline` plus `childIdsOf` make of a run's whole checkpoint list, read through the
|
|
5959
|
+
* store's aggregates instead: the checkpoints outside wide fans, one {@link FanSummary} per wide fan,
|
|
5960
|
+
* and the run's children capped at {@link SUMMARY_CHILD_LIMIT} with their count.
|
|
5482
5961
|
*
|
|
5483
|
-
*
|
|
5484
|
-
* (
|
|
5485
|
-
* and
|
|
5486
|
-
* `
|
|
5487
|
-
*
|
|
5962
|
+
* What it reads besides the aggregates: the rows outside wide fans, every folded `fan:` checkpoint
|
|
5963
|
+
* (one per settled wave), up to {@link FAN_SUMMARY_FAILURES} failed rows per wide fan, the first
|
|
5964
|
+
* child-edge rows, and — while a wide child fan is in flight — that fan's completed `signal:child:`
|
|
5965
|
+
* rows, whose `ok: false` payload is what marks a failed child.
|
|
5966
|
+
*
|
|
5967
|
+
* `childCount` counts each `spawn:` checkpoint as one child: the engine always writes the child's id
|
|
5968
|
+
* as its output, which is what `childIdsOf` reads.
|
|
5488
5969
|
*/
|
|
5489
|
-
declare
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
* belong to the same panel as {@link listRuns}: a tenant that can list its runs has to be able to
|
|
5507
|
-
* see what it may filter them by, or its console offers a blank dropdown.
|
|
5508
|
-
*
|
|
5509
|
-
* Returns `[]` when the underlying store does not implement the enumeration — an empty picker with
|
|
5510
|
-
* free-text entry still standing, not an error.
|
|
5511
|
-
*/
|
|
5512
|
-
abstract runValueFacets(axis: RunValueAxis, query: RunFacetQuery, opts?: RunValueFacetOptions): Promise<RunValueFacetRow[]>;
|
|
5513
|
-
/**
|
|
5514
|
-
* Bulk-resolve {@link RunWaiting} for an arbitrary set of run ids — for a consumer with its OWN
|
|
5515
|
-
* filtered/paginated run listing (so it isn't just `listRuns` under another name) that needs to know
|
|
5516
|
-
* which of ITS runs are parked on a breakpoint (or any other event wait) without re-deriving the bulk
|
|
5517
|
-
* waiter scan itself or reaching for raw SQL against `durable_step_checkpoints`. A `Record` (not a
|
|
5518
|
-
* `Map`) because `ProxyRunGateway` serialises the reply over the transport as plain JSON. Entries are
|
|
5519
|
-
* present ONLY for runs currently waiting — an unknown id, a non-suspended id, and a suspended id
|
|
5520
|
-
* parked on something non-event (a bare `ctx.sleep`, an in-flight step) are simply absent, same as a
|
|
5521
|
-
* `listRuns` row with no `waiting`.
|
|
5522
|
-
*/
|
|
5523
|
-
abstract waitingFor(runIds: string[]): Promise<Record<string, RunWaiting>>;
|
|
5524
|
-
/** Per-group worker health (queue backlog + live worker heartbeats). On the control plane this is
|
|
5525
|
-
* every group; over a tenant proxy the operator scopes it to the tenant's own groups. */
|
|
5526
|
-
abstract workerHealth(): Promise<GroupHealth[]>;
|
|
5527
|
-
abstract cancel(runId: string, opts?: {
|
|
5528
|
-
compensate?: boolean;
|
|
5529
|
-
}): Promise<RunResult | null>;
|
|
5530
|
-
abstract retry(runId: string): Promise<RunResult | null>;
|
|
5531
|
-
abstract continue(runId: string): Promise<RunResult | null>;
|
|
5532
|
-
/** Re-dispatch every remote step of a run stuck `pending` — the operator recovery for a LOST step
|
|
5533
|
-
* dispatch (crashed worker / dropped job) that no automatic path re-drives. Returns the run's status
|
|
5534
|
-
* plus how many steps were re-dispatched, or null if the run is unknown. */
|
|
5535
|
-
abstract redispatchPending(runId: string): Promise<(RunResult & {
|
|
5536
|
-
redispatched: number;
|
|
5537
|
-
}) | null>;
|
|
5538
|
-
abstract retryWithInput(runId: string, input: unknown): Promise<{
|
|
5539
|
-
runId: string;
|
|
5540
|
-
} | null>;
|
|
5541
|
-
/** Live lifecycle events for one run; returns an unsubscribe fn. Framework-agnostic (no rxjs). */
|
|
5542
|
-
abstract subscribe(runId: string, onEvent: (event: EngineEvent) => void): () => void;
|
|
5543
|
-
}
|
|
5970
|
+
declare function summarizeRunFromStore(store: CheckpointAggregatingStore, runId: string, over: number, stats?: CheckpointStat[]): Promise<{
|
|
5971
|
+
timeline: StepCheckpoint[];
|
|
5972
|
+
fans: FanSummary[];
|
|
5973
|
+
children: string[];
|
|
5974
|
+
childCount: number;
|
|
5975
|
+
}>;
|
|
5976
|
+
/** What `pageFan` makes of a run's whole checkpoint list, read one page at a time from the store. */
|
|
5977
|
+
declare function pageFanFromStore(store: CheckpointAggregatingStore, runId: string, group: string, query: FanPageQuery, stats?: CheckpointStat[]): Promise<FanPage>;
|
|
5978
|
+
/**
|
|
5979
|
+
* The ETag of a summarized run detail: the run row as read (so any run field that changes shows)
|
|
5980
|
+
* plus its checkpoint buckets, and the threshold it was summarized with.
|
|
5981
|
+
*/
|
|
5982
|
+
declare function runDetailEtag(run: WorkflowRun, stats: CheckpointStat[], over: number): string;
|
|
5983
|
+
/** The ETag of one page of a fan: its group's buckets and the page asked for. */
|
|
5984
|
+
declare function fanPageEtag(group: string, stats: CheckpointStat[], query: FanPageQuery): string;
|
|
5985
|
+
/** Whether an `If-None-Match` header value names `etag` (weak comparison, as RFC 9110 asks for). */
|
|
5986
|
+
declare function etagMatches(ifNoneMatch: string | undefined, etag: string): boolean;
|
|
5544
5987
|
|
|
5545
5988
|
/**
|
|
5546
5989
|
* Resolve WHAT a suspended run is parked on from the token of the {@link SignalWaiter} it registered.
|
|
@@ -5573,9 +6016,10 @@ declare function indexWaitersByRun(waiters: readonly SignalWaiter[]): Map<string
|
|
|
5573
6016
|
|
|
5574
6017
|
/**
|
|
5575
6018
|
* The parent of a child run whose id the engine minted: a `ctx.all` child
|
|
5576
|
-
* (`<parent>.all.<seq>.<i>`, or `.w<k>.<i>` under a `concurrency` limit)
|
|
5577
|
-
* `ctx.startChild` child without an explicit id (`<parent>.child.<seq>`)
|
|
5578
|
-
* run, including a child started with a
|
|
6019
|
+
* (`<parent>.all.<seq>.<i>`, or `.w<k>.<i>` under a `concurrency` limit), a `ctx.child` /
|
|
6020
|
+
* `ctx.startChild` child without an explicit id (`<parent>.child.<seq>`), or the onError handler of
|
|
6021
|
+
* a failed run (`<parent>.onError.<attempt>`). Undefined for any other run, including a child started with a
|
|
6022
|
+
* caller-chosen id.
|
|
5579
6023
|
*/
|
|
5580
6024
|
declare function parentRunIdOf(runId: string): string | undefined;
|
|
5581
6025
|
|
|
@@ -5622,11 +6066,21 @@ declare class CodecStateStore implements StateStore {
|
|
|
5622
6066
|
/** Encodes like {@link saveCheckpoint}. Bound only when the inner store has it, so the engine's
|
|
5623
6067
|
* plain-save fallback still kicks in through the wrapper. */
|
|
5624
6068
|
readonly saveCheckpointIfPending?: (checkpoint: StepCheckpoint) => Promise<boolean>;
|
|
6069
|
+
/** Encodes each checkpoint like {@link saveCheckpoint}. Bound only when the inner store has it. */
|
|
6070
|
+
readonly saveCheckpointsIfPending?: (checkpoints: StepCheckpoint[]) => Promise<boolean[]>;
|
|
5625
6071
|
/** Forwarded verbatim — a count reads no payload. Bound only when the inner store has it. */
|
|
5626
6072
|
readonly countCheckpoints?: (runId: string, fromSeq: number, toSeq: number, statuses: StepCheckpoint['status'][]) => Promise<number>;
|
|
5627
6073
|
/** Forwarded verbatim — retention selects by status/updatedAt/scope, never by payload. Bound only
|
|
5628
6074
|
* when the inner store prunes, so the retention poller still sees (and warns about) its absence. */
|
|
5629
6075
|
readonly pruneTerminalRuns?: (policy: RetentionPolicy, nowMs: number, limit: number) => Promise<number>;
|
|
6076
|
+
/** Forwarded verbatim — the buckets aggregate names, statuses and timestamps, never a payload.
|
|
6077
|
+
* Bound only when the inner store aggregates, so the run detail's fallback still applies. */
|
|
6078
|
+
readonly checkpointStats?: (runId: string, opts?: {
|
|
6079
|
+
group?: string | undefined;
|
|
6080
|
+
}) => Promise<CheckpointStat[]>;
|
|
6081
|
+
/** Filters on unencoded columns, then decodes the rows like {@link listCheckpoints}. Bound only
|
|
6082
|
+
* when the inner store has it. */
|
|
6083
|
+
readonly queryCheckpoints?: (runId: string, query: CheckpointQuery) => Promise<StepCheckpoint[]>;
|
|
5630
6084
|
/** Forwarded verbatim — a count reads no payload. Bound only when the inner store counts, so the
|
|
5631
6085
|
* engine's facet/listing fallback still applies through the wrapper. */
|
|
5632
6086
|
readonly countRuns?: (query: Omit<RunQuery, 'limit' | 'offset'>) => Promise<number>;
|
|
@@ -5726,12 +6180,17 @@ declare function eventMatchOf(token: string): Record<string, unknown>;
|
|
|
5726
6180
|
declare function eventMatches(payload: unknown, match: Record<string, unknown>): boolean;
|
|
5727
6181
|
|
|
5728
6182
|
interface MetricsSnapshot {
|
|
6183
|
+
/** `routed`: failures handed to an onError handler; `unrouted`: routes the engine could not apply. */
|
|
5729
6184
|
runs: {
|
|
5730
6185
|
started: number;
|
|
5731
6186
|
completed: number;
|
|
5732
6187
|
failed: number;
|
|
5733
6188
|
suspended: number;
|
|
6189
|
+
routed: number;
|
|
6190
|
+
unrouted: number;
|
|
5734
6191
|
};
|
|
6192
|
+
/** Routed failures by error code (`*` for a failure without one). */
|
|
6193
|
+
routedByCode: Record<string, number>;
|
|
5735
6194
|
steps: {
|
|
5736
6195
|
started: number;
|
|
5737
6196
|
completed: number;
|
|
@@ -6081,6 +6540,11 @@ declare class InMemoryStateStore implements StateStore {
|
|
|
6081
6540
|
* so this lets the benchmark contrast "fetch N, scan in JS" against "fetch the k that match".
|
|
6082
6541
|
*/
|
|
6083
6542
|
lastCheckpointRowsRead: number;
|
|
6543
|
+
/**
|
|
6544
|
+
* Test/observability hook: checkpoint rows materialized since construction, across every
|
|
6545
|
+
* checkpoint read that returns rows — what a run-detail benchmark compares between paths.
|
|
6546
|
+
*/
|
|
6547
|
+
checkpointRowsRead: number;
|
|
6084
6548
|
private key;
|
|
6085
6549
|
/** Drop then re-add a run's normalized attribute rows so the index tracks its current attributes. */
|
|
6086
6550
|
private reindexAttributes;
|
|
@@ -6094,6 +6558,7 @@ declare class InMemoryStateStore implements StateStore {
|
|
|
6094
6558
|
getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null>;
|
|
6095
6559
|
saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
|
|
6096
6560
|
saveCheckpointIfPending(checkpoint: StepCheckpoint): Promise<boolean>;
|
|
6561
|
+
saveCheckpointsIfPending(checkpoints: StepCheckpoint[]): Promise<boolean[]>;
|
|
6097
6562
|
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
6098
6563
|
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
6099
6564
|
listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]>;
|
|
@@ -6155,6 +6620,11 @@ declare class InMemoryStateStore implements StateStore {
|
|
|
6155
6620
|
deleteSchedule(id: string): Promise<boolean>;
|
|
6156
6621
|
listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]>;
|
|
6157
6622
|
listCheckpoints(runId: string): Promise<StepCheckpoint[]>;
|
|
6623
|
+
private runCheckpoints;
|
|
6624
|
+
checkpointStats(runId: string, opts?: {
|
|
6625
|
+
group?: string | undefined;
|
|
6626
|
+
}): Promise<CheckpointStat[]>;
|
|
6627
|
+
queryCheckpoints(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]>;
|
|
6158
6628
|
getLatestCheckpointByName(runId: string, name: string): Promise<StepCheckpoint | undefined>;
|
|
6159
6629
|
countCheckpoints(runId: string, fromSeq: number, toSeq: number, statuses: StepCheckpoint['status'][]): Promise<number>;
|
|
6160
6630
|
listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]>;
|
|
@@ -6200,4 +6670,4 @@ declare function singletonAdmissionDenialPatch(runs: WorkflowRun[], runId: strin
|
|
|
6200
6670
|
updatedAt: Date;
|
|
6201
6671
|
} | undefined;
|
|
6202
6672
|
|
|
6203
|
-
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AllOptions, type AllStepsOptions, type AnnouncedWorkflow, type AnnouncementEvidence, type AttributeFilter, type AttributeOp, type AttributePredicateOperand, type AttributeValue, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, type ChildWait, CodecStateStore, type ConcurrencyConfig, ConcurrencyLimitError, type ConcurrencyQuota, ContinueAsNew, type ControlMessage, type ControlPlane, DEFAULT_CONCURRENCY_STATUSES, DEFAULT_PARTITION, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type Disagreement, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, type DynamicWorkflowCtx, ENGINE_MINTED_TAG_PREFIXES, EVENT_BUFFER_SCAN_LIMIT, EVENT_TOKEN_PREFIX, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, EventAccumulators, type EventBatchConfig, type FanJoin, type FanWait, FatalError, GatherError, type GroupHealth, type Heartbeat, type HeartbeatSighting, 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, NestedWorkflowCallError, NonDeterminismError, type PartitionSighting, type PayloadCodec, type QueueConfig, QueueController, RUN_VALUE_FACET_LIMIT, RUN_VALUE_FACET_SCAN, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunFacetQuery, type RunFacetRow, RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunScope, type RunStatus, type RunValueAxis, type RunValueFacetOptions, type RunValueFacetOrder, type RunValueFacetRow, type RunWaiting, SINGLETON_ACTIVE_STATUSES, SINGLETON_ADMITTED_TAG, STATE_STORE, STATE_STORE_CANONICAL, type ScalarAttributeFilter, ScheduleAlreadyExistsError, ScheduleClient, type ScheduleClientOptions, type ScheduleDescription, type ScheduleHost, type ScheduleListQuery, ScheduleNotFoundError, type ScheduleOptions, type ScheduleQuery, type ScheduleRecord, 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 StepScope, type StepUndo, type StoreTransaction, type SubProcessHandle, TERMINAL_RUN_STATUSES, TRANSPORT, TRANSPORT_CANONICAL, type TenantEvent, type Transport, type UndoOf, type UpdateResult, type UpdateValidator, VERSION_UNDECLARED_TAG, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, type WorkflowAnnouncement, WorkflowBlocked, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, type WorkflowDirectory, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRegistration, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, aggregateAnnouncements, announcementsOf, applyAttributeQuery, assertConcurrency, attributeColumnFor, attributeOperand, attributePredicateOperands, axisIsRunColumn, bindWorkflowClass, breakpointToken, buildWorkflowDirectory, canRoute, capableWorkers, classifyWaiterToken, clearDurableExecutionWrappers, clearTerminalSingletonAdmission, collectMetrics, concurrencyTag, controlPlaneDescriptor, countRuns, coveredTokens, createStepLogger, currentStep, currentStepScope, currentWorkflowCtx, debug, describeWorker, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, facetOrigin, hasDurableExecutionWrappers, heartbeatStatus, indexWaitersByRun, info, isEngineMintedTag, isEventToken, isLegacyDescriptor, isNonEmptyRunScope, isWorkflowControlFlowSignal, listSignalWaitersOfRuns, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, nextCronFireMs, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, parentRunIdOf, parseDuration, partitionOfToken, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveConcurrency, resolveRouting, resolveRunWaiting, runDurableExecution, runInStepLogger, runInStepScope, runInWorkflowCtx, runOutsideWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduledRunId, singletonAdmissionDenialPatch, singletonAdmissionTags, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };
|
|
6673
|
+
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AllOptions, type AllSettledOptions, type AllStepsOptions, type AllStepsSettledOptions, type AnnouncedWorkflow, type AnnouncementEvidence, type AttributeFilter, type AttributeOp, type AttributePredicateOperand, type AttributeValue, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CHILD_EDGE_PREFIXES, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type CheckpointAggregatingStore, type CheckpointNameKind, type CheckpointQuery, type CheckpointStat, type ChildCallOptions, type ChildWait, CodecStateStore, type ConcurrencyConfig, ConcurrencyLimitError, type ConcurrencyQuota, ContinueAsNew, type ControlMessage, type ControlPlane, DEFAULT_CONCURRENCY_STATUSES, DEFAULT_PARTITION, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type Disagreement, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, type DynamicWorkflowCtx, ENGINE_MINTED_TAG_PREFIXES, EVENT_BUFFER_SCAN_LIMIT, EVENT_TOKEN_PREFIX, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, EventAccumulators, type EventBatchConfig, FAN_SUMMARY_FAILURES, type FanJoin, type FanPage, type FanPageQuery, type FanSummary, type FanWait, FatalError, GatherError, type GatherItemFailure, type GroupHealth, HANDOFF_SEQ_BASE, type Heartbeat, type HeartbeatSighting, type HeartbeatStatus, type HistoryEvent, InMemoryAdmissionBackend, InMemoryStateStore, InMemoryTransport, type InferSearchAttributes, LEGACY_V1_CAPABILITIES, LEGACY_V1_PROTOCOL, type MetricsCollector, type MetricsSnapshot, type NamedTransport, type NegotiateOptions, type NegotiationOutcome, type NegotiationReason, type NegotiationResult, NestedWorkflowCallError, NonDeterminismError, type OnErrorInput, type OnErrorRoute, type PartitionSighting, type PayloadCodec, type QueueConfig, QueueController, RUN_VALUE_FACET_LIMIT, RUN_VALUE_FACET_SCAN, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDetailOptions, type RunDispatcher, type RunFacetQuery, type RunFacetRow, RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunScope, type RunStatus, type RunValueAxis, type RunValueFacetOptions, type RunValueFacetOrder, type RunValueFacetRow, type RunWaiting, SINGLETON_ACTIVE_STATUSES, SINGLETON_ADMITTED_TAG, STATE_STORE, STATE_STORE_CANONICAL, SUMMARY_CHILD_LIMIT, type ScalarAttributeFilter, ScheduleAlreadyExistsError, ScheduleClient, type ScheduleClientOptions, type ScheduleDescription, type ScheduleHost, type ScheduleListQuery, ScheduleNotFoundError, type ScheduleOptions, type ScheduleQuery, type ScheduleRecord, type ScheduledWorkflow, type SearchAttributes, type SearchAttributesSchema, type Settled, 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 StepScope, type StepUndo, type StoreTransaction, type SubProcessHandle, TERMINAL_RUN_STATUSES, TRANSPORT, TRANSPORT_CANONICAL, type TenantEvent, type Transport, type UndoOf, type UpdateResult, type UpdateValidator, VERSION_UNDECLARED_TAG, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, type WorkflowAnnouncement, WorkflowBlocked, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, type WorkflowDirectory, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRegistration, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, aggregateAnnouncements, aggregatesCheckpoints, announcementsOf, applyAttributeQuery, assertConcurrency, assertRoutes, attributeColumnFor, attributeOperand, attributePredicateOperands, axisIsRunColumn, bindWorkflowClass, breakpointToken, buildWorkflowDirectory, canRoute, capableWorkers, checkpointNameKind, checkpointStatsOf, childIdsOf, classifyWaiterToken, clearDurableExecutionWrappers, clearTerminalSingletonAdmission, codeAndDetails, codeOf, collectMetrics, concurrencyTag, controlPlaneDescriptor, countRuns, coveredTokens, createStepLogger, currentStep, currentStepScope, currentWorkflowCtx, debug, describeWorker, descriptorHash, detailsOf, error, etagMatches, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, facetOrigin, fanPageBounds, fanPageEtag, foldedCount, handoffHandlerId, handoffName, hasDurableExecutionWrappers, heartbeatStatus, indexWaitersByRun, info, isEngineMintedTag, isEventToken, isFailedMember, isLegacyDescriptor, isNonEmptyRunScope, isWorkflowControlFlowSignal, listSignalWaitersOfRuns, liveHandoff, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, nextCronFireMs, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, onErrorRunId, pageFan, pageFanFromStore, parentRunIdOf, parseDuration, partitionOfToken, planDispatch, prevCronFireMs, queryCheckpointsOf, readSearchAttributes, requiredCapabilities, resolveConcurrency, resolveRouting, resolveRunWaiting, retiredHandoffName, routeFor, runDetailEtag, runDurableExecution, runInStepLogger, runInStepScope, runInWorkflowCtx, runOutsideWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduledRunId, singletonAdmissionDenialPatch, singletonAdmissionTags, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, summarizeFan, summarizeRunFromStore, summarizeTimeline, tenantGroup, useDurableExecution, warn, workflowName };
|