@dudousxd/nestjs-durable-core 0.71.1 → 0.72.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -935,10 +935,23 @@ interface StateStore {
935
935
  * first), cascading to their child rows exactly like {@link deleteRun}. Returns how many runs were
936
936
  * deleted — call again while it returns `limit` to drain a large backlog in bounded batches.
937
937
  *
938
+ * A policy with a {@link RetentionPolicy.scope} only ever selects (and counts, for `maxCount`) runs
939
+ * matching that scope.
940
+ *
938
941
  * Optional: only adapters that implement a bulk prune provide it; the retention poller no-ops with a
939
942
  * warning when the configured store omits it. See {@link RetentionPolicy} for the keep/prune rule.
940
943
  */
941
944
  pruneTerminalRuns?(policy: RetentionPolicy, nowMs: number, limit: number): Promise<number>;
945
+ /**
946
+ * Hard-delete a BATCH of runs and all of their rows in one go — exactly {@link deleteRun} applied to
947
+ * every id (checkpoints, signal waiters, attribute rows, then the runs), but as a handful of
948
+ * `IN (...)` statements in one transaction instead of four round-trips per run. Ids that don't exist
949
+ * are ignored. Like {@link deleteRun} it removes exactly the listed runs; the engine's
950
+ * `purgeRuns` walks the child edges first.
951
+ *
952
+ * Optional: a store that omits it still works — the engine falls back to one {@link deleteRun} per id.
953
+ */
954
+ deleteRuns?(runIds: string[]): Promise<void>;
942
955
  getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null>;
943
956
  /**
944
957
  * Persist a checkpoint and advance the run atomically. Durable semantics depend on this
@@ -1031,7 +1044,30 @@ interface StateStore {
1031
1044
  * adapters implement it; `ctx.transaction` errors on a store without it.
1032
1045
  */
1033
1046
  transaction?<T>(work: (tx: StoreTransaction) => Promise<T>): Promise<T>;
1047
+ /** Insert or fully replace the schedule `record.id`. */
1048
+ saveSchedule?(record: ScheduleRecord): Promise<void>;
1049
+ /** The schedule `id`, or null. */
1050
+ getSchedule?(id: string): Promise<ScheduleRecord | null>;
1051
+ /**
1052
+ * Patch the schedule `id`. With `expectedNextFireAt`, a compare-and-set: the patch applies only if
1053
+ * the stored `nextFireAt` still equals it (`null` matching `NULL`), which is how two schedulers racing
1054
+ * on the same due schedule agree on who advanced it. Returns whether a row was updated.
1055
+ */
1056
+ updateSchedule?(id: string, patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>, expectedNextFireAt?: number | null): Promise<boolean>;
1057
+ /** Delete the schedule `id`. Returns whether it existed. Its past runs are left alone. */
1058
+ deleteSchedule?(id: string): Promise<boolean>;
1059
+ /** Schedules matching `query`, ordered by `nextFireAt` ascending (never-firing last), then `id`. */
1060
+ listSchedules?(query: ScheduleQuery): Promise<ScheduleRecord[]>;
1034
1061
  listRuns(query: RunQuery): Promise<WorkflowRun[]>;
1062
+ /**
1063
+ * How many runs match `query` — a single `COUNT(*)` over the same predicates {@link listRuns}
1064
+ * applies, without materializing a row. What the start-time concurrency quota asks on every start
1065
+ * (`tag = concurrency:<key> AND status IN (...)`), so it must stay an aggregate, not a listing.
1066
+ *
1067
+ * Optional: a store that omits it still works — the engine falls back to summing {@link runFacets}
1068
+ * cells, then to counting a {@link listRuns} result.
1069
+ */
1070
+ countRuns?(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number>;
1035
1071
  /**
1036
1072
  * Count the runs matching `query`, grouped by `(status, origin)` — the totals behind a console's
1037
1073
  * status and origin chips, in ONE aggregate instead of a full listing the caller counts in memory.
@@ -1080,6 +1116,44 @@ interface StateStore {
1080
1116
  */
1081
1117
  listCheckpointsByNamePrefix?(runId: string, prefixes: string[]): Promise<StepCheckpoint[]>;
1082
1118
  }
1119
+ /**
1120
+ * A persisted schedule as the STORE sees it: a handful of queryable columns plus two JSON documents
1121
+ * the store keeps verbatim (`spec`, `state`) and never interprets. The engine's schedule client owns
1122
+ * their meaning (cron/interval math, overlap, catch-up) — so a store only has to persist rows and
1123
+ * answer "which unpaused schedules are due by T".
1124
+ */
1125
+ interface ScheduleRecord {
1126
+ /** Caller-chosen, stable id (e.g. `digest:user-42`) — also part of every run id it starts. */
1127
+ id: string;
1128
+ /** Partition: the namespace its runs are stamped with, and which schedulers fire it. */
1129
+ namespace: string;
1130
+ /** Registered workflow name the schedule starts. */
1131
+ workflow: string;
1132
+ /** A paused schedule is never due. */
1133
+ paused: boolean;
1134
+ /** Epoch ms at which it is next due (jitter included), or null when it will never fire again. */
1135
+ nextFireAt: number | null;
1136
+ /** Labels to list/filter schedules by (also stamped onto the runs it starts). */
1137
+ tags?: string[] | undefined;
1138
+ /** The schedule's definition — opaque to the store. */
1139
+ spec: Record<string, unknown>;
1140
+ /** The schedule's bookkeeping (last fire, last run id, last error…) — opaque to the store. */
1141
+ state: Record<string, unknown>;
1142
+ createdAt: Date;
1143
+ updatedAt: Date;
1144
+ }
1145
+ /** Filter for {@link StateStore.listSchedules}. Every predicate is ANDed; absent = unrestricted. */
1146
+ interface ScheduleQuery {
1147
+ namespace?: string | undefined;
1148
+ workflow?: string | undefined;
1149
+ /** Only schedules carrying this tag. */
1150
+ tag?: string | undefined;
1151
+ paused?: boolean | undefined;
1152
+ /** Only DUE schedules: unpaused, `nextFireAt <= dueBy`. */
1153
+ dueBy?: number | undefined;
1154
+ limit?: number | undefined;
1155
+ offset?: number | undefined;
1156
+ }
1083
1157
  /** The terminal run statuses — a run in one of these is finished and will never change on its own.
1084
1158
  * Only these are eligible for retention pruning (a {@link RetentionPolicy} targeting a non-terminal
1085
1159
  * status would race the engine and delete live work). */
@@ -1100,7 +1174,27 @@ interface RetentionPolicy {
1100
1174
  statuses: RunStatus[];
1101
1175
  maxAge?: number | string;
1102
1176
  maxCount?: number;
1177
+ /**
1178
+ * Confine the policy to the runs matching these predicates (same semantics as the {@link RunQuery}
1179
+ * fields of the same names) — e.g. `{ namespace: 'acme' }` for one tenant, `{ tags: ['chat'] }` for
1180
+ * one kind of run, `{ workflows: ['report', 'report.branch'] }` for a workflow family. Absent = every
1181
+ * run in `statuses`. `maxCount` is then counted WITHIN the scope ("keep acme's newest 100").
1182
+ *
1183
+ * A scope matches runs by their own row, so a child run is only covered if it matches too (children
1184
+ * inherit their parent's `namespace`, but not its `tags`) — scope by `namespace` or by `workflows`
1185
+ * when a whole run tree must age out together.
1186
+ */
1187
+ scope?: RunScope | undefined;
1103
1188
  }
1189
+ /**
1190
+ * The run predicates a bulk operation (a scoped {@link RetentionPolicy}, `engine.purgeRuns`) is
1191
+ * confined to — the identity axes of a {@link RunQuery}: which tenant (`namespace`), which kind of
1192
+ * run (`workflow`/`tags`), which business entity (`attributes`). Status, origin and paging are left
1193
+ * out on purpose: each bulk operation owns its own status rule.
1194
+ */
1195
+ type RunScope = Pick<RunQuery, 'workflow' | 'workflows' | 'tag' | 'tags' | 'namespace' | 'namespaces' | 'attributes'>;
1196
+ /** True when `scope` sets at least one predicate — a bulk delete refuses an empty (match-all) scope. */
1197
+ declare function isNonEmptyRunScope(scope: RunScope | undefined): boolean;
1104
1198
  /** Typed, queryable per-run data — exact values for `eq`/`ne`, numbers/strings for range ops. */
1105
1199
  type SearchAttributes = Record<string, string | number | boolean>;
1106
1200
  /**
@@ -2280,6 +2374,41 @@ interface WorkflowCtx<A extends SearchAttributes = SearchAttributes> {
2280
2374
  */
2281
2375
  localStep<TOutput>(name: string, fn: (log: StepLogger) => Promise<TOutput>, options?: StepOptions): Promise<TOutput>;
2282
2376
  }
2377
+ /**
2378
+ * {@link WorkflowCtx} with ONE signature per method: the string-addressed forms of the four overloaded
2379
+ * methods (`step`, `child`, `startChild`, `all`), everything else unchanged.
2380
+ *
2381
+ * For code that drives the ctx DYNAMICALLY — an interpreter that runs a user-defined graph and only
2382
+ * ever knows workflow/step names as strings — and for test fakes. An overloaded method is awkward to
2383
+ * satisfy structurally (a fake must implement every overload, and a hand-written narrow interface
2384
+ * has to guess which overload TS will match), so depend on this instead:
2385
+ *
2386
+ * ```ts
2387
+ * type InterpreterCtx = Pick<DynamicWorkflowCtx, 'runId' | 'localStep' | 'child' | 'all' | 'sleep'>;
2388
+ * class Interpreter { constructor(private readonly ctx: InterpreterCtx) {} }
2389
+ *
2390
+ * async run(ctx: WorkflowCtx, input: Input) {
2391
+ * return new Interpreter(ctx).run(); // no cast — a WorkflowCtx IS a DynamicWorkflowCtx
2392
+ * }
2393
+ * ```
2394
+ *
2395
+ * Every `WorkflowCtx<A>` is assignable to `DynamicWorkflowCtx<A>` (guarded by
2396
+ * `dynamic-workflow-ctx.type-test.ts`), and a `Pick` of it is a plain object literal in a test.
2397
+ */
2398
+ interface DynamicWorkflowCtx<A extends SearchAttributes = SearchAttributes> extends Omit<WorkflowCtx<A>, 'step' | 'child' | 'startChild' | 'all'> {
2399
+ /** {@link WorkflowCtx.step} by step name (a cross-runtime handler, or a `@Step` by its name). */
2400
+ step<TOutput = unknown, TInput = unknown>(name: string, input: TInput, opts?: StepDispatchOpts & {
2401
+ compensate?: string;
2402
+ }): Promise<TOutput>;
2403
+ /** {@link WorkflowCtx.child} by workflow name. */
2404
+ child<TOutput = unknown>(workflow: string, input: unknown, options?: string | ChildCallOptions): Promise<TOutput>;
2405
+ /** {@link WorkflowCtx.startChild} by workflow name. */
2406
+ startChild(workflow: string, input: unknown, options?: string | ChildCallOptions): Promise<string>;
2407
+ /** {@link WorkflowCtx.all} by workflow name. */
2408
+ all<TOutput = unknown>(workflow: string, inputs: unknown[], opts?: {
2409
+ mode?: 'waitAll' | 'failFast';
2410
+ }): Promise<TOutput[]>;
2411
+ }
2283
2412
  /** Result of executing or resuming a workflow run. */
2284
2413
  interface RunResult {
2285
2414
  runId: string;
@@ -2376,6 +2505,32 @@ declare function runInWorkflowCtx<T>(ctx: WorkflowCtx, fn: () => T): T;
2376
2505
  * ambient workflow context (by design — a handler is not the workflow body).
2377
2506
  */
2378
2507
  declare function currentWorkflowCtx(): WorkflowCtx | undefined;
2508
+ /**
2509
+ * The ambient STEP scope: which workflow ctx's checkpointed step body (if any) is executing on this
2510
+ * async path. The engine installs it around every in-body step execution (`ctx.localStep`,
2511
+ * `ctx.transaction`, and everything built on them) so the ctx primitives can refuse to run from
2512
+ * inside a step body — see {@link NestedWorkflowCallError}. `owner` is the identity of the ctx whose
2513
+ * step is running, so a DIFFERENT run's body executed inline from a step (e.g. a step that signals a
2514
+ * run which resumes on this async path) is never mistaken for a nested call.
2515
+ *
2516
+ * Shared per process under a `Symbol.for` key, for the same duplicate-copy reason as the ctx storage.
2517
+ */
2518
+ interface StepScope {
2519
+ readonly owner: object;
2520
+ readonly step: string;
2521
+ }
2522
+ /** Run `fn` as the body of step `step` of the ctx identified by `owner`. Engine-internal. */
2523
+ declare function runInStepScope<T>(owner: object, step: string, fn: () => T): T;
2524
+ /** The step body currently executing on this async path, or `undefined` outside one. */
2525
+ declare function currentStepScope(): StepScope | undefined;
2526
+ /**
2527
+ * Run `fn` with NO ambient workflow ctx and no step scope — for a dispatched `@Step` handler. A
2528
+ * handler is not the workflow body (on a remote worker it never sees one), but an in-process
2529
+ * transport invokes it on the body's async path, where the parent's ctx would otherwise leak in and
2530
+ * turn a handler's `MyWorkflow.start()` into a journal-corrupting `ctx.startChild` of a parent that
2531
+ * is already suspended. Clearing it makes in-process and remote handlers behave identically.
2532
+ */
2533
+ declare function runOutsideWorkflowCtx<T>(fn: () => T): T;
2379
2534
 
2380
2535
  /**
2381
2536
  * Run `fn` with `logger` as the ambient step logger. Engine-internal: wraps every execution of a
@@ -2490,6 +2645,60 @@ declare const CONTROL_FLOW_SIGNAL: unique symbol;
2490
2645
  */
2491
2646
  declare function isWorkflowControlFlowSignal(error: unknown): boolean;
2492
2647
 
2648
+ /**
2649
+ * A start-time concurrency quota for ONE start: at most `limit` runs sharing `key` may be in flight
2650
+ * (in `countStatuses`) at once; a start that would exceed it is rejected with
2651
+ * {@link ConcurrencyLimitError} before any run is created.
2652
+ *
2653
+ * The key is global — not per workflow — so different workflows started with the same key share the
2654
+ * quota (e.g. `tenant:acme` capping every kind of run a tenant can have executing). Passed per start
2655
+ * as `StartOptions.concurrency`, or derived from the input by a workflow's {@link ConcurrencyConfig}.
2656
+ */
2657
+ interface ConcurrencyQuota {
2658
+ /** The quota bucket, e.g. `tenant:acme`. Stamped on the run as the tag `concurrency:<key>`. */
2659
+ key: string;
2660
+ /** Max runs of this key in flight at once. `limit <= 0` rejects every start. */
2661
+ limit: number;
2662
+ /**
2663
+ * Which statuses occupy a slot. Default: every non-terminal status
2664
+ * ({@link DEFAULT_CONCURRENCY_STATUSES}). Narrow it to e.g. `['pending', 'running']` so runs parked
2665
+ * on a human (`suspended`) stop counting against the quota.
2666
+ */
2667
+ countStatuses?: RunStatus[] | undefined;
2668
+ }
2669
+ /**
2670
+ * A workflow's standing concurrency quota, declared at registration (`register(..., { concurrency })`
2671
+ * / `@Workflow({ concurrency })`): the key is derived from each start's input, and the limit may be a
2672
+ * function of the key (per-tenant plans). A `StartOptions.concurrency` on one start overrides it.
2673
+ */
2674
+ interface ConcurrencyConfig {
2675
+ /** Derive the quota key from the input. Return `undefined` to leave this start unlimited. */
2676
+ key: (input: unknown) => string | undefined;
2677
+ /** Max in-flight runs per key — a number, or resolved per key (e.g. from the tenant's plan). */
2678
+ limit: number | ((key: string) => number | Promise<number>);
2679
+ /** Which statuses occupy a slot. See {@link ConcurrencyQuota.countStatuses}. */
2680
+ countStatuses?: RunStatus[] | undefined;
2681
+ }
2682
+ /** Every non-terminal status: what "in flight" means when a quota doesn't narrow it. */
2683
+ declare const DEFAULT_CONCURRENCY_STATUSES: readonly RunStatus[];
2684
+ /** The tag a quota-bearing run carries, so its siblings can be counted by one tag+status query. */
2685
+ declare function concurrencyTag(key: string): string;
2686
+ /** Resolve the quota that applies to one start: the per-start override, else the workflow's config. */
2687
+ declare function resolveConcurrency(override: ConcurrencyQuota | undefined, config: ConcurrencyConfig | undefined, input: unknown): Promise<ConcurrencyQuota | undefined>;
2688
+ /** Count the runs matching `query` as cheaply as the store allows (count → facets → listing). */
2689
+ declare function countRuns(store: StateStore, query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number>;
2690
+ /**
2691
+ * Reject a start that would exceed `quota`: counts the in-flight runs carrying the quota's tag and
2692
+ * throws {@link ConcurrencyLimitError} once they reach the limit.
2693
+ *
2694
+ * A SOFT cap under a race: the count and the run's creation are separate statements, so N starts
2695
+ * racing on the last free slot can each see it free (the same guarantee a hand-rolled
2696
+ * `SELECT count(*)` gate gives). It is exact whenever starts for a key are not simultaneous, and the
2697
+ * overshoot is bounded by the number of truly concurrent starts. Use `singleton` when you need a
2698
+ * strict, queueing per-key limit instead of a rejecting one.
2699
+ */
2700
+ declare function assertConcurrency(store: StateStore, workflow: string, quota: ConcurrencyQuota): Promise<void>;
2701
+
2493
2702
  /**
2494
2703
  * Back-compat alias of {@link WorkflowCtx}. `localStep` — the checkpointed in-process step primitive
2495
2704
  * used for saga compensation — is now part of the public {@link WorkflowCtx}, so this type adds
@@ -3010,6 +3219,173 @@ type RoutingResolution = RoutableResolution | BlockedResolution;
3010
3219
  */
3011
3220
  declare function resolveRouting(handler: CapabilityRequirement, workers: readonly (RawWorkerDescriptor | WorkerDescriptor)[]): RoutingResolution;
3012
3221
 
3222
+ /**
3223
+ * A schedule definition — what `engine.schedules.create/upsert` take. Temporal-style: a persisted,
3224
+ * runtime-managed recurring start of `workflow` with `input`, fired by every driving engine's timer
3225
+ * poll (safe with many workers: each window's run id is deterministic, `start` is idempotent, and
3226
+ * advancing the schedule is a compare-and-set).
3227
+ */
3228
+ interface ScheduleOptions {
3229
+ /** Stable id, unique per store (e.g. `digest:user-42`). Part of every run id it starts. */
3230
+ id: string;
3231
+ /** The workflow to start — a registered name or `@Workflow` class. */
3232
+ workflow: WorkflowRef;
3233
+ /** The input every run starts with. */
3234
+ input?: unknown;
3235
+ /** Cron expression (5 fields, or 6 with leading seconds). Needs the `cron-parser` peer. */
3236
+ cron?: string | undefined;
3237
+ /** Fixed interval (`'15m'`, or ms), windows aligned to the epoch. Exclusive with `cron`. */
3238
+ every?: string | number | undefined;
3239
+ /** IANA timezone the cron is evaluated in (e.g. `America/Sao_Paulo`). Default UTC. */
3240
+ timezone?: string | undefined;
3241
+ /**
3242
+ * Delay each fire by up to this much (`'30s'` or ms) — a stable per-(schedule, window) offset, so
3243
+ * thousands of schedules on the same cron don't all start in the same second.
3244
+ */
3245
+ jitter?: string | number | undefined;
3246
+ /**
3247
+ * The previous run of this schedule is still in flight when the next window comes due:
3248
+ * `'allow'` (default) starts the new one anyway; `'skip'` skips that window.
3249
+ */
3250
+ overlap?: 'allow' | 'skip' | undefined;
3251
+ /**
3252
+ * Windows missed while nothing polled (all schedulers down): `'latest'` (default) fires the most
3253
+ * recent missed window once; `'skip'` drops them and waits for the next window. Never more than one
3254
+ * catch-up run per schedule.
3255
+ */
3256
+ catchup?: 'latest' | 'skip' | undefined;
3257
+ /** Create paused (never due until `resume`). On `upsert`, omit to keep the current paused state. */
3258
+ paused?: boolean | undefined;
3259
+ /** Free-form note shown with the schedule (why it exists / why it's paused). */
3260
+ note?: string | undefined;
3261
+ /** Namespace of the schedule and of the runs it starts. Defaults to the engine's own namespace. */
3262
+ namespace?: string | undefined;
3263
+ /** Labels to find the schedule by — also stamped on every run it starts (plus `schedule:<id>`). */
3264
+ tags?: string[] | undefined;
3265
+ /** Search attributes stamped on every run it starts. */
3266
+ searchAttributes?: SearchAttributes | undefined;
3267
+ /** Dispatch priority for the runs it starts. */
3268
+ priority?: number | undefined;
3269
+ /**
3270
+ * A start-time concurrency quota applied to every run it starts (see `StartOptions.concurrency`):
3271
+ * a window whose start would exceed it is recorded as the schedule's `lastError` and skipped, and
3272
+ * the schedule moves on to its next window.
3273
+ */
3274
+ concurrency?: ConcurrencyQuota | undefined;
3275
+ }
3276
+ /** A schedule as `engine.schedules.get/list` describe it. */
3277
+ interface ScheduleDescription {
3278
+ id: string;
3279
+ workflow: string;
3280
+ input: unknown;
3281
+ namespace: string;
3282
+ cron?: string | undefined;
3283
+ everyMs?: number | undefined;
3284
+ timezone?: string | undefined;
3285
+ jitterMs?: number | undefined;
3286
+ overlap: 'allow' | 'skip';
3287
+ catchup: 'latest' | 'skip';
3288
+ paused: boolean;
3289
+ note?: string | undefined;
3290
+ tags?: string[] | undefined;
3291
+ searchAttributes?: SearchAttributes | undefined;
3292
+ priority?: number | undefined;
3293
+ concurrency?: ConcurrencyQuota | undefined;
3294
+ /** When it is next due (jitter included), or null if it never fires again / paused. */
3295
+ nextFireAt: Date | null;
3296
+ /** The last window it fired for, and the run that window started. */
3297
+ lastFireAt?: Date | undefined;
3298
+ lastRunId?: string | undefined;
3299
+ /** How many windows it has fired (manual triggers excluded). */
3300
+ fires: number;
3301
+ /** The last start failure (e.g. a concurrency limit), cleared by the next successful start. */
3302
+ lastError?: string | undefined;
3303
+ createdAt: Date;
3304
+ updatedAt: Date;
3305
+ }
3306
+ /** Filter for `engine.schedules.list`. */
3307
+ type ScheduleListQuery = Omit<ScheduleQuery, 'dueBy'>;
3308
+ /** Thrown by `engine.schedules.create` when the id is taken (use `upsert` to replace). */
3309
+ declare class ScheduleAlreadyExistsError extends Error {
3310
+ readonly scheduleId: string;
3311
+ constructor(scheduleId: string);
3312
+ }
3313
+ /** Thrown by `engine.schedules.*` on an id that doesn't exist. */
3314
+ declare class ScheduleNotFoundError extends Error {
3315
+ readonly scheduleId: string;
3316
+ constructor(scheduleId: string);
3317
+ }
3318
+ /** The engine surface the schedule client drives. */
3319
+ interface ScheduleHost {
3320
+ start(workflow: string, input: unknown, runId: string, opts?: StartOptions): Promise<RunResult>;
3321
+ getRun(runId: string): Promise<WorkflowRun | null>;
3322
+ }
3323
+ /** Engine-level knobs for the client. */
3324
+ interface ScheduleClientOptions {
3325
+ /** The engine's namespace: the default for new schedules, and which ones `tick` fires. */
3326
+ namespace?: string | undefined;
3327
+ clock?: (() => number) | undefined;
3328
+ }
3329
+ /**
3330
+ * Persisted, runtime-managed schedules — `engine.schedules`. Unlike the code-registered
3331
+ * `schedules` module option, these live in the store: create/update/pause/delete them at runtime
3332
+ * (one per user, per tenant, per automation…), and every driving engine's timer poll fires the due
3333
+ * ones via {@link tick}.
3334
+ *
3335
+ * Multi-worker safety comes from two properties, not from a lock: a window's run id is deterministic
3336
+ * (`sched:<id>:<windowMs>`), so racing starts of the same window collapse into one run; and a
3337
+ * schedule is advanced with a compare-and-set on its `nextFireAt`, so exactly one poller moves it on.
3338
+ * A crash between starting the run and advancing the schedule just re-fires the (idempotent) start.
3339
+ */
3340
+ declare class ScheduleClient {
3341
+ private readonly store;
3342
+ private readonly host;
3343
+ private readonly options;
3344
+ constructor(store: StateStore, host: ScheduleHost, options?: ScheduleClientOptions);
3345
+ private now;
3346
+ /** Whether the store persists schedules (implements the schedule methods). */
3347
+ get supported(): boolean;
3348
+ private requireStore;
3349
+ /** Create a schedule. Throws {@link ScheduleAlreadyExistsError} if the id is taken. */
3350
+ create(opts: ScheduleOptions): Promise<ScheduleDescription>;
3351
+ /**
3352
+ * Create the schedule, or replace the definition of an existing one (its history — last fire, last
3353
+ * run, fire count — is kept). The next fire is recomputed from now under the new definition, so a
3354
+ * window that already fired is never fired again by an upsert.
3355
+ */
3356
+ upsert(opts: ScheduleOptions): Promise<ScheduleDescription>;
3357
+ /** The schedule `id`, or null. */
3358
+ get(id: string): Promise<ScheduleDescription | null>;
3359
+ /** Schedules matching `query`, soonest-due first. */
3360
+ list(query?: ScheduleListQuery): Promise<ScheduleDescription[]>;
3361
+ /** Delete the schedule. Runs it already started are left alone. Returns whether it existed. */
3362
+ delete(id: string): Promise<boolean>;
3363
+ /** Stop firing until {@link resume}. `note` records why (shown by `get`/`list`). */
3364
+ pause(id: string, note?: string): Promise<ScheduleDescription>;
3365
+ /**
3366
+ * Fire again from the next window after now — the windows skipped while paused are NOT caught up.
3367
+ */
3368
+ resume(id: string): Promise<ScheduleDescription>;
3369
+ /**
3370
+ * Start one run of the schedule right now, outside its cadence (paused or not). The run id is
3371
+ * `sched:<id>:manual:<nowMs>`; it doesn't move the schedule's next fire.
3372
+ */
3373
+ trigger(id: string): Promise<RunResult>;
3374
+ /**
3375
+ * Fire every due schedule (in this engine's namespace; all namespaces for an operator engine):
3376
+ * start its window's run and advance it to the next window. Called by the NestJS timer poller on
3377
+ * each tick when `persistedSchedules` is on; call it yourself from any other driver. Returns the
3378
+ * run ids started (or re-found, for an idempotent re-fire).
3379
+ */
3380
+ tick(nowMs?: number): Promise<string[]>;
3381
+ /** Fire one due schedule and advance it. Returns the run id started, if any. */
3382
+ private fire;
3383
+ /** `overlap: 'skip'` and the previous run of this schedule is still in flight. */
3384
+ private overlapping;
3385
+ private mustGet;
3386
+ private write;
3387
+ }
3388
+
3013
3389
  type WorkflowFn = (ctx: InternalWorkflowCtx, input: unknown) => Promise<unknown>;
3014
3390
  /**
3015
3391
  * Options for {@link WorkflowEngine.start}.
@@ -3055,6 +3431,12 @@ interface StartOptions {
3055
3431
  * maps here), so one DB-less-tenant-facing engine can create runs across many namespaces.
3056
3432
  */
3057
3433
  namespace?: string | undefined;
3434
+ /**
3435
+ * A start-time concurrency quota for this start — at most `limit` runs sharing `key` in flight;
3436
+ * over it, `start` throws {@link ConcurrencyLimitError} and creates nothing. Overrides the
3437
+ * workflow's registered `concurrency`. See {@link ConcurrencyQuota}.
3438
+ */
3439
+ concurrency?: ConcurrencyQuota | undefined;
3058
3440
  }
3059
3441
  /**
3060
3442
  * Serialize runs of a workflow that share a key — a durable, FIFO mutex (e.g. one pipeline per base).
@@ -3305,6 +3687,12 @@ declare class WorkflowEngine {
3305
3687
  private readonly runDispatcher;
3306
3688
  /** Per-key serialization for singleton workflows (admission, back-pressure, notify-on-release). */
3307
3689
  private readonly singletons;
3690
+ /**
3691
+ * Persisted, runtime-managed schedules: create/upsert/pause/resume/delete/list/trigger them, and
3692
+ * `tick()` fires the due ones (the NestJS timer poller does it when `persistedSchedules` is on).
3693
+ * Needs a store that persists schedules — every bundled adapter does. See {@link ScheduleClient}.
3694
+ */
3695
+ readonly schedules: ScheduleClient;
3308
3696
  /** Every registered workflow, keyed by `name@version` — so old versions stay runnable. */
3309
3697
  private readonly workflows;
3310
3698
  /** The newest registered version per workflow name — used to `start` new runs. */
@@ -3380,6 +3768,8 @@ declare class WorkflowEngine {
3380
3768
  register(name: string, version: string, fn: WorkflowFn, opts?: {
3381
3769
  tags?: string[] | undefined;
3382
3770
  singleton?: SingletonConfig | undefined;
3771
+ /** Start-time concurrency quota — see {@link ConcurrencyConfig}. */
3772
+ concurrency?: ConcurrencyConfig | undefined;
3383
3773
  executionTimeout?: string | number | undefined;
3384
3774
  validateInput?: ((input: unknown) => void | Promise<void>) | undefined;
3385
3775
  /** Typed/validated `searchAttributes` shape — see `RegisteredWorkflow.searchAttributesSchema`. */
@@ -3426,6 +3816,7 @@ declare class WorkflowEngine {
3426
3816
  executor: WorkflowExecutor;
3427
3817
  tags?: string[];
3428
3818
  singleton?: SingletonConfig;
3819
+ concurrency?: ConcurrencyConfig;
3429
3820
  executionTimeout?: string | number;
3430
3821
  validateInput?: (input: unknown) => void | Promise<void>;
3431
3822
  /** Capabilities a live worker must advertise to run this remote workflow's turns (handshake §7.5). */
@@ -3451,6 +3842,7 @@ declare class WorkflowEngine {
3451
3842
  version?: string;
3452
3843
  tags?: string[];
3453
3844
  singleton?: SingletonConfig;
3845
+ concurrency?: ConcurrencyConfig;
3454
3846
  executionTimeout?: string | number;
3455
3847
  validateInput?: (input: unknown) => void | Promise<void>;
3456
3848
  /** Capabilities a live worker must advertise to run this workflow's turns (handshake §7.5). */
@@ -3504,7 +3896,23 @@ declare class WorkflowEngine {
3504
3896
  start<TInput>(workflow: string, input: TInput, runId: string, opts?: StartOptions): Promise<RunResult>;
3505
3897
  /** Read a run's current persisted state (or null if unknown). A thin pass-through to the store. */
3506
3898
  getRun(runId: string): Promise<WorkflowRun | null>;
3899
+ /**
3900
+ * Re-execute a run's body (replaying its checkpoints). This is the EXPLICIT entry point: besides
3901
+ * driving a live run, it re-drives a `failed` run — the manual retry (prefer {@link requeue}, which
3902
+ * also resets the failure state so replay re-attempts the failed parts). Completed / cancelled /
3903
+ * dead runs are never re-executed. The engine's own implicit wake-ups (signals, step results,
3904
+ * timers, redelivered dispatches) go through {@link resumeImplicit}, which treats `failed` as
3905
+ * terminal too.
3906
+ */
3507
3907
  resume(runId: string): Promise<RunResult>;
3908
+ /**
3909
+ * {@link resume} for every IMPLICIT wake-up — a delivered signal/child completion, a late step
3910
+ * result, a due timer, a redelivered dispatch, a queue-slot wake. A `failed` run is terminal to
3911
+ * these: only an explicit retry ({@link requeue} / {@link resume}) may re-drive it. Otherwise a
3912
+ * stale waiter or a late result left behind by a failed run silently re-executes its body.
3913
+ */
3914
+ private resumeImplicit;
3915
+ private resumeRun;
3508
3916
  /**
3509
3917
  * The registration for an UNREGISTERED run, INHERITED from its nearest REMOTE ancestor — or
3510
3918
  * `undefined` if it has none (the skew-protection error case in {@link resume}). Callers check the
@@ -3878,6 +4286,43 @@ declare class WorkflowEngine {
3878
4286
  * its worker (its next checkpoint write fails). Returns the number of runs deleted (0 if absent).
3879
4287
  */
3880
4288
  deleteRun(runId: string): Promise<number>;
4289
+ /**
4290
+ * Hard-delete EVERY run matching `scope` — plus, by default, each one's whole child subtree — in
4291
+ * bounded batches. The "forget this tenant" / "drop this feature's history" operation: where
4292
+ * {@link deleteRun} removes one tree you already know the id of, this drains everything a scope
4293
+ * selects (`{ namespace: 'acme' }`, `{ tag: 'tenant:acme' }`, `{ workflows: [...] }`, attribute
4294
+ * predicates …) through the store API, so no caller has to reach into the `durable_*` tables.
4295
+ *
4296
+ * - **Live runs** (not yet terminal) are {@link cancel cancelled} first (plain cancel, no saga
4297
+ * undo), which tells any worker holding one to stop, and then deleted with the rest. Pass
4298
+ * `cancelLive: false` to leave live runs (and live descendants of finished ones) alone and
4299
+ * delete terminal history only.
4300
+ * - **Children** are found through the same parent→child edges as {@link getRunChildren} and deleted
4301
+ * with their root even when they don't match `scope` themselves (children inherit `namespace`,
4302
+ * but not `tags`). `children: false` deletes exactly the matching runs.
4303
+ * - **Batched**: `batchSize` runs (default 500) per round, each round one bulk
4304
+ * {@link StateStore.deleteRuns} (falling back to per-run {@link StateStore.deleteRun}).
4305
+ *
4306
+ * An EMPTY scope is rejected — it would delete every run in the store. Returns how many runs were
4307
+ * deleted (children included).
4308
+ */
4309
+ purgeRuns(scope: RunScope, opts?: {
4310
+ batchSize?: number;
4311
+ cancelLive?: boolean;
4312
+ children?: boolean;
4313
+ }): Promise<number>;
4314
+ /**
4315
+ * {@link purgeRuns} for one namespace — every run (and child) a tenant/partition owns. Children
4316
+ * inherit their parent's namespace, so a namespace purge is complete by construction.
4317
+ */
4318
+ purgeNamespace(namespace: string, opts?: {
4319
+ batchSize?: number;
4320
+ cancelLive?: boolean;
4321
+ }): Promise<number>;
4322
+ /** The given runs plus every descendant, children before parents. One waiter scan for the batch. */
4323
+ private collectSubtrees;
4324
+ /** Bulk-delete through the store's `deleteRuns`, or one `deleteRun` per id when it has none. */
4325
+ private deleteRunIds;
3881
4326
  /**
3882
4327
  * Cascade cancellation to a run's children — both awaited (`ctx.child`, found via its live
3883
4328
  * `child:<id>` waiter) and fire-and-forget (`ctx.startChild`, found via its `spawn:<id>`
@@ -4400,6 +4845,19 @@ declare class FatalError extends Error {
4400
4845
  readonly code?: string | undefined;
4401
4846
  constructor(message: string, code?: string);
4402
4847
  }
4848
+ /**
4849
+ * Thrown by `start` when a run would exceed its concurrency quota: `active` runs sharing the quota
4850
+ * `key` are already in flight (in the quota's counted statuses) and the `limit` is `limit`. Nothing
4851
+ * was created — the start is rejected up front, so the caller can shed load or answer "try again in a
4852
+ * moment" (e.g. map it to HTTP 429). See `StartOptions.concurrency` / `ConcurrencyConfig`.
4853
+ */
4854
+ declare class ConcurrencyLimitError extends Error {
4855
+ readonly workflow: string;
4856
+ readonly key: string;
4857
+ readonly limit: number;
4858
+ readonly active: number;
4859
+ constructor(workflow: string, key: string, limit: number, active: number);
4860
+ }
4403
4861
  /**
4404
4862
  * Thrown by `start` when a singleton workflow's wait queue is full: the count of in-flight + gated
4405
4863
  * runs sharing the key already equals `limit + maxQueueDepth`, so admitting another would let the
@@ -4467,6 +4925,26 @@ declare class NonDeterminismError extends Error {
4467
4925
  readonly seq: number;
4468
4926
  constructor(runId: string, seq: number, expected: string, recorded: string);
4469
4927
  }
4928
+ /**
4929
+ * Thrown AT THE CALL SITE when a workflow-ctx primitive (`ctx.startChild`, `ctx.child`, `ctx.step`,
4930
+ * `ctx.sleep`, `ctx.sideEffect`, … — or a `MyWorkflow.start()`/`.execute()` static, which route to
4931
+ * them through the ambient ctx) is called from INSIDE the body of a checkpointed step
4932
+ * (`ctx.localStep`, `ctx.transaction`, `ctx.sideEffect`, `ctx.now`, `ctx.task`'s dispatch).
4933
+ *
4934
+ * A step body runs once and is replayed from its checkpoint WITHOUT re-running, so a primitive it
4935
+ * called claims a journal position on the first run that no replay ever claims again: every later
4936
+ * position shifts and the run dies on its next replay with a `NonDeterminismError` far from the
4937
+ * cause. Failing here instead names the real mistake. Move the call out of the step body (into the
4938
+ * workflow body), or — from a dispatched `@Step` handler — start a top-level run.
4939
+ *
4940
+ * A `FatalError` (code `nested_workflow_call`): the step is not retried, the run fails.
4941
+ */
4942
+ declare class NestedWorkflowCallError extends FatalError {
4943
+ readonly runId: string;
4944
+ readonly primitive: string;
4945
+ readonly step: string;
4946
+ constructor(runId: string, primitive: string, step: string);
4947
+ }
4470
4948
  /**
4471
4949
  * Thrown by `ctx.all` when one or more parallel child workflows fail. Carries the per-item failures
4472
4950
  * (input index, child run id, error message) and presents an aggregate message summarizing the count
@@ -4660,7 +5138,7 @@ declare const RUN_VALUE_FACET_SCAN = 5000;
4660
5138
  * sets exactly that), so it stays offered — just after the tags a human wrote. `version:undeclared`
4661
5139
  * is engine-minted too but is a single fixed value, so it competes fairly and is not listed here.
4662
5140
  */
4663
- declare const ENGINE_MINTED_TAG_PREFIXES: readonly ["singleton:"];
5141
+ declare const ENGINE_MINTED_TAG_PREFIXES: readonly ["singleton:", "concurrency:"];
4664
5142
  /** Is this a tag the engine mints one of per key? See {@link ENGINE_MINTED_TAG_PREFIXES}. */
4665
5143
  declare function isEngineMintedTag(value: string | null): boolean;
4666
5144
  /**
@@ -4863,6 +5341,22 @@ declare class CodecStateStore implements StateStore {
4863
5341
  * Bound the same conditional way as {@link runFacets} so absence is reported, not faked.
4864
5342
  */
4865
5343
  readonly runValueFacets?: (axis: RunValueAxis, query: RunFacetQuery, opts?: RunValueFacetOptions) => Promise<RunValueFacetRow[]>;
5344
+ /** Forwarded verbatim (deletes touch no payload). Bound only when the inner store has it, so the
5345
+ * engine's per-run fallback still kicks in through the wrapper. */
5346
+ readonly deleteRuns?: (runIds: string[]) => Promise<void>;
5347
+ /** Forwarded verbatim — retention selects by status/updatedAt/scope, never by payload. Bound only
5348
+ * when the inner store prunes, so the retention poller still sees (and warns about) its absence. */
5349
+ readonly pruneTerminalRuns?: (policy: RetentionPolicy, nowMs: number, limit: number) => Promise<number>;
5350
+ /** Forwarded verbatim — a count reads no payload. Bound only when the inner store counts, so the
5351
+ * engine's facet/listing fallback still applies through the wrapper. */
5352
+ readonly countRuns?: (query: Omit<RunQuery, 'limit' | 'offset'>) => Promise<number>;
5353
+ /** Schedules persist their run `input` inside `spec` — encoded like any other payload. Bound only
5354
+ * when the inner store persists schedules, so `engine.schedules` reports absence faithfully. */
5355
+ readonly saveSchedule?: (record: ScheduleRecord) => Promise<void>;
5356
+ readonly getSchedule?: (id: string) => Promise<ScheduleRecord | null>;
5357
+ readonly updateSchedule?: (id: string, patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>, expectedNextFireAt?: number | null) => Promise<boolean>;
5358
+ readonly deleteSchedule?: (id: string) => Promise<boolean>;
5359
+ readonly listSchedules?: (query: ScheduleQuery) => Promise<ScheduleRecord[]>;
4866
5360
  constructor(inner: StateStore, codec: PayloadCodec);
4867
5361
  private enc;
4868
5362
  private dec;
@@ -4870,6 +5364,9 @@ declare class CodecStateStore implements StateStore {
4870
5364
  private decRun;
4871
5365
  private encCp;
4872
5366
  private decCp;
5367
+ private encSpec;
5368
+ private encSchedule;
5369
+ private decSchedule;
4873
5370
  ensureSchema(): Promise<void>;
4874
5371
  createRun(run: WorkflowRun): Promise<void>;
4875
5372
  updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void>;
@@ -5039,6 +5536,12 @@ declare function scheduledRunId(key: string, everyMs: number, nowMs: number): st
5039
5536
  * interval resolves to the same fire time — and thus the same idempotent run id.
5040
5537
  */
5041
5538
  declare function prevCronFireMs(expr: string, nowMs: number, timezone?: string): number;
5539
+ /**
5540
+ * Epoch ms of the first cron fire STRICTLY after `afterMs`, evaluated in `timezone` (default UTC) —
5541
+ * the forward counterpart of {@link prevCronFireMs}, used by persisted schedules to compute when a
5542
+ * schedule is next due.
5543
+ */
5544
+ declare function nextCronFireMs(expr: string, afterMs: number, timezone?: string): number;
5042
5545
  /**
5043
5546
  * Start each schedule's current-window run. The run id is the time bucket (a fixed-interval index,
5044
5547
  * or the cron fire time) and `engine.start` is idempotent, so firing this on an interval — or
@@ -5297,6 +5800,8 @@ declare class InMemoryStateStore implements StateStore {
5297
5800
  updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void>;
5298
5801
  getRun(runId: string): Promise<WorkflowRun | null>;
5299
5802
  deleteRun(runId: string): Promise<void>;
5803
+ deleteRuns(runIds: string[]): Promise<void>;
5804
+ pruneTerminalRuns(policy: RetentionPolicy, nowMs: number, limit: number): Promise<number>;
5300
5805
  getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null>;
5301
5806
  saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
5302
5807
  listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
@@ -5343,11 +5848,18 @@ declare class InMemoryStateStore implements StateStore {
5343
5848
  * {@link listRuns} (which then sorts + pages it) and {@link runFacets} (which groups it). */
5344
5849
  private matching;
5345
5850
  listRuns(query: RunQuery): Promise<WorkflowRun[]>;
5851
+ countRuns(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number>;
5346
5852
  runFacets(query: RunFacetQuery): Promise<RunFacetRow[]>;
5347
5853
  /** Counted over the newest `scan` matching runs for EVERY axis, not just `tag`: this store holds
5348
5854
  * its runs in a Map with no index to group by, so the bound that the SQL stores need only for tags
5349
5855
  * is the honest one to apply here throughout. */
5350
5856
  runValueFacets(axis: RunValueAxis, query: RunFacetQuery, opts?: RunValueFacetOptions): Promise<RunValueFacetRow[]>;
5857
+ private readonly schedules;
5858
+ saveSchedule(record: ScheduleRecord): Promise<void>;
5859
+ getSchedule(id: string): Promise<ScheduleRecord | null>;
5860
+ updateSchedule(id: string, patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>, expectedNextFireAt?: number | null): Promise<boolean>;
5861
+ deleteSchedule(id: string): Promise<boolean>;
5862
+ listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]>;
5351
5863
  listCheckpoints(runId: string): Promise<StepCheckpoint[]>;
5352
5864
  getLatestCheckpointByName(runId: string, name: string): Promise<StepCheckpoint | undefined>;
5353
5865
  listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]>;
@@ -5379,4 +5891,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
5379
5891
  onControl(handler: (msg: ControlMessage) => void): void;
5380
5892
  }
5381
5893
 
5382
- export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, 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, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, 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, 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, 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, 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 RunStatus, type RunValueAxis, type RunValueFacetOptions, type RunValueFacetOrder, type RunValueFacetRow, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, type ScalarAttributeFilter, 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, 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, attributeColumnFor, attributeOperand, attributePredicateOperands, axisIsRunColumn, bindWorkflowClass, breakpointToken, buildWorkflowDirectory, canRoute, capableWorkers, classifyWaiterToken, clearDurableExecutionWrappers, collectMetrics, controlPlaneDescriptor, coveredTokens, createStepLogger, currentStep, currentWorkflowCtx, debug, describeWorker, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, facetOrigin, hasDurableExecutionWrappers, heartbeatStatus, indexWaitersByRun, info, isEngineMintedTag, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, parseDuration, partitionOfToken, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runDurableExecution, runInStepLogger, runInWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };
5894
+ export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, 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, 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, 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, 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, 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, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, nextCronFireMs, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, parseDuration, partitionOfToken, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveConcurrency, resolveRouting, resolveRunWaiting, runDurableExecution, runInStepLogger, runInStepScope, runInWorkflowCtx, runOutsideWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };