@dudousxd/nestjs-durable-core 0.71.0 → 0.72.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.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;
@@ -2490,6 +2619,60 @@ declare const CONTROL_FLOW_SIGNAL: unique symbol;
2490
2619
  */
2491
2620
  declare function isWorkflowControlFlowSignal(error: unknown): boolean;
2492
2621
 
2622
+ /**
2623
+ * A start-time concurrency quota for ONE start: at most `limit` runs sharing `key` may be in flight
2624
+ * (in `countStatuses`) at once; a start that would exceed it is rejected with
2625
+ * {@link ConcurrencyLimitError} before any run is created.
2626
+ *
2627
+ * The key is global — not per workflow — so different workflows started with the same key share the
2628
+ * quota (e.g. `tenant:acme` capping every kind of run a tenant can have executing). Passed per start
2629
+ * as `StartOptions.concurrency`, or derived from the input by a workflow's {@link ConcurrencyConfig}.
2630
+ */
2631
+ interface ConcurrencyQuota {
2632
+ /** The quota bucket, e.g. `tenant:acme`. Stamped on the run as the tag `concurrency:<key>`. */
2633
+ key: string;
2634
+ /** Max runs of this key in flight at once. `limit <= 0` rejects every start. */
2635
+ limit: number;
2636
+ /**
2637
+ * Which statuses occupy a slot. Default: every non-terminal status
2638
+ * ({@link DEFAULT_CONCURRENCY_STATUSES}). Narrow it to e.g. `['pending', 'running']` so runs parked
2639
+ * on a human (`suspended`) stop counting against the quota.
2640
+ */
2641
+ countStatuses?: RunStatus[] | undefined;
2642
+ }
2643
+ /**
2644
+ * A workflow's standing concurrency quota, declared at registration (`register(..., { concurrency })`
2645
+ * / `@Workflow({ concurrency })`): the key is derived from each start's input, and the limit may be a
2646
+ * function of the key (per-tenant plans). A `StartOptions.concurrency` on one start overrides it.
2647
+ */
2648
+ interface ConcurrencyConfig {
2649
+ /** Derive the quota key from the input. Return `undefined` to leave this start unlimited. */
2650
+ key: (input: unknown) => string | undefined;
2651
+ /** Max in-flight runs per key — a number, or resolved per key (e.g. from the tenant's plan). */
2652
+ limit: number | ((key: string) => number | Promise<number>);
2653
+ /** Which statuses occupy a slot. See {@link ConcurrencyQuota.countStatuses}. */
2654
+ countStatuses?: RunStatus[] | undefined;
2655
+ }
2656
+ /** Every non-terminal status: what "in flight" means when a quota doesn't narrow it. */
2657
+ declare const DEFAULT_CONCURRENCY_STATUSES: readonly RunStatus[];
2658
+ /** The tag a quota-bearing run carries, so its siblings can be counted by one tag+status query. */
2659
+ declare function concurrencyTag(key: string): string;
2660
+ /** Resolve the quota that applies to one start: the per-start override, else the workflow's config. */
2661
+ declare function resolveConcurrency(override: ConcurrencyQuota | undefined, config: ConcurrencyConfig | undefined, input: unknown): Promise<ConcurrencyQuota | undefined>;
2662
+ /** Count the runs matching `query` as cheaply as the store allows (count → facets → listing). */
2663
+ declare function countRuns(store: StateStore, query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number>;
2664
+ /**
2665
+ * Reject a start that would exceed `quota`: counts the in-flight runs carrying the quota's tag and
2666
+ * throws {@link ConcurrencyLimitError} once they reach the limit.
2667
+ *
2668
+ * A SOFT cap under a race: the count and the run's creation are separate statements, so N starts
2669
+ * racing on the last free slot can each see it free (the same guarantee a hand-rolled
2670
+ * `SELECT count(*)` gate gives). It is exact whenever starts for a key are not simultaneous, and the
2671
+ * overshoot is bounded by the number of truly concurrent starts. Use `singleton` when you need a
2672
+ * strict, queueing per-key limit instead of a rejecting one.
2673
+ */
2674
+ declare function assertConcurrency(store: StateStore, workflow: string, quota: ConcurrencyQuota): Promise<void>;
2675
+
2493
2676
  /**
2494
2677
  * Back-compat alias of {@link WorkflowCtx}. `localStep` — the checkpointed in-process step primitive
2495
2678
  * used for saga compensation — is now part of the public {@link WorkflowCtx}, so this type adds
@@ -3010,6 +3193,173 @@ type RoutingResolution = RoutableResolution | BlockedResolution;
3010
3193
  */
3011
3194
  declare function resolveRouting(handler: CapabilityRequirement, workers: readonly (RawWorkerDescriptor | WorkerDescriptor)[]): RoutingResolution;
3012
3195
 
3196
+ /**
3197
+ * A schedule definition — what `engine.schedules.create/upsert` take. Temporal-style: a persisted,
3198
+ * runtime-managed recurring start of `workflow` with `input`, fired by every driving engine's timer
3199
+ * poll (safe with many workers: each window's run id is deterministic, `start` is idempotent, and
3200
+ * advancing the schedule is a compare-and-set).
3201
+ */
3202
+ interface ScheduleOptions {
3203
+ /** Stable id, unique per store (e.g. `digest:user-42`). Part of every run id it starts. */
3204
+ id: string;
3205
+ /** The workflow to start — a registered name or `@Workflow` class. */
3206
+ workflow: WorkflowRef;
3207
+ /** The input every run starts with. */
3208
+ input?: unknown;
3209
+ /** Cron expression (5 fields, or 6 with leading seconds). Needs the `cron-parser` peer. */
3210
+ cron?: string | undefined;
3211
+ /** Fixed interval (`'15m'`, or ms), windows aligned to the epoch. Exclusive with `cron`. */
3212
+ every?: string | number | undefined;
3213
+ /** IANA timezone the cron is evaluated in (e.g. `America/Sao_Paulo`). Default UTC. */
3214
+ timezone?: string | undefined;
3215
+ /**
3216
+ * Delay each fire by up to this much (`'30s'` or ms) — a stable per-(schedule, window) offset, so
3217
+ * thousands of schedules on the same cron don't all start in the same second.
3218
+ */
3219
+ jitter?: string | number | undefined;
3220
+ /**
3221
+ * The previous run of this schedule is still in flight when the next window comes due:
3222
+ * `'allow'` (default) starts the new one anyway; `'skip'` skips that window.
3223
+ */
3224
+ overlap?: 'allow' | 'skip' | undefined;
3225
+ /**
3226
+ * Windows missed while nothing polled (all schedulers down): `'latest'` (default) fires the most
3227
+ * recent missed window once; `'skip'` drops them and waits for the next window. Never more than one
3228
+ * catch-up run per schedule.
3229
+ */
3230
+ catchup?: 'latest' | 'skip' | undefined;
3231
+ /** Create paused (never due until `resume`). On `upsert`, omit to keep the current paused state. */
3232
+ paused?: boolean | undefined;
3233
+ /** Free-form note shown with the schedule (why it exists / why it's paused). */
3234
+ note?: string | undefined;
3235
+ /** Namespace of the schedule and of the runs it starts. Defaults to the engine's own namespace. */
3236
+ namespace?: string | undefined;
3237
+ /** Labels to find the schedule by — also stamped on every run it starts (plus `schedule:<id>`). */
3238
+ tags?: string[] | undefined;
3239
+ /** Search attributes stamped on every run it starts. */
3240
+ searchAttributes?: SearchAttributes | undefined;
3241
+ /** Dispatch priority for the runs it starts. */
3242
+ priority?: number | undefined;
3243
+ /**
3244
+ * A start-time concurrency quota applied to every run it starts (see `StartOptions.concurrency`):
3245
+ * a window whose start would exceed it is recorded as the schedule's `lastError` and skipped, and
3246
+ * the schedule moves on to its next window.
3247
+ */
3248
+ concurrency?: ConcurrencyQuota | undefined;
3249
+ }
3250
+ /** A schedule as `engine.schedules.get/list` describe it. */
3251
+ interface ScheduleDescription {
3252
+ id: string;
3253
+ workflow: string;
3254
+ input: unknown;
3255
+ namespace: string;
3256
+ cron?: string | undefined;
3257
+ everyMs?: number | undefined;
3258
+ timezone?: string | undefined;
3259
+ jitterMs?: number | undefined;
3260
+ overlap: 'allow' | 'skip';
3261
+ catchup: 'latest' | 'skip';
3262
+ paused: boolean;
3263
+ note?: string | undefined;
3264
+ tags?: string[] | undefined;
3265
+ searchAttributes?: SearchAttributes | undefined;
3266
+ priority?: number | undefined;
3267
+ concurrency?: ConcurrencyQuota | undefined;
3268
+ /** When it is next due (jitter included), or null if it never fires again / paused. */
3269
+ nextFireAt: Date | null;
3270
+ /** The last window it fired for, and the run that window started. */
3271
+ lastFireAt?: Date | undefined;
3272
+ lastRunId?: string | undefined;
3273
+ /** How many windows it has fired (manual triggers excluded). */
3274
+ fires: number;
3275
+ /** The last start failure (e.g. a concurrency limit), cleared by the next successful start. */
3276
+ lastError?: string | undefined;
3277
+ createdAt: Date;
3278
+ updatedAt: Date;
3279
+ }
3280
+ /** Filter for `engine.schedules.list`. */
3281
+ type ScheduleListQuery = Omit<ScheduleQuery, 'dueBy'>;
3282
+ /** Thrown by `engine.schedules.create` when the id is taken (use `upsert` to replace). */
3283
+ declare class ScheduleAlreadyExistsError extends Error {
3284
+ readonly scheduleId: string;
3285
+ constructor(scheduleId: string);
3286
+ }
3287
+ /** Thrown by `engine.schedules.*` on an id that doesn't exist. */
3288
+ declare class ScheduleNotFoundError extends Error {
3289
+ readonly scheduleId: string;
3290
+ constructor(scheduleId: string);
3291
+ }
3292
+ /** The engine surface the schedule client drives. */
3293
+ interface ScheduleHost {
3294
+ start(workflow: string, input: unknown, runId: string, opts?: StartOptions): Promise<RunResult>;
3295
+ getRun(runId: string): Promise<WorkflowRun | null>;
3296
+ }
3297
+ /** Engine-level knobs for the client. */
3298
+ interface ScheduleClientOptions {
3299
+ /** The engine's namespace: the default for new schedules, and which ones `tick` fires. */
3300
+ namespace?: string | undefined;
3301
+ clock?: (() => number) | undefined;
3302
+ }
3303
+ /**
3304
+ * Persisted, runtime-managed schedules — `engine.schedules`. Unlike the code-registered
3305
+ * `schedules` module option, these live in the store: create/update/pause/delete them at runtime
3306
+ * (one per user, per tenant, per automation…), and every driving engine's timer poll fires the due
3307
+ * ones via {@link tick}.
3308
+ *
3309
+ * Multi-worker safety comes from two properties, not from a lock: a window's run id is deterministic
3310
+ * (`sched:<id>:<windowMs>`), so racing starts of the same window collapse into one run; and a
3311
+ * schedule is advanced with a compare-and-set on its `nextFireAt`, so exactly one poller moves it on.
3312
+ * A crash between starting the run and advancing the schedule just re-fires the (idempotent) start.
3313
+ */
3314
+ declare class ScheduleClient {
3315
+ private readonly store;
3316
+ private readonly host;
3317
+ private readonly options;
3318
+ constructor(store: StateStore, host: ScheduleHost, options?: ScheduleClientOptions);
3319
+ private now;
3320
+ /** Whether the store persists schedules (implements the schedule methods). */
3321
+ get supported(): boolean;
3322
+ private requireStore;
3323
+ /** Create a schedule. Throws {@link ScheduleAlreadyExistsError} if the id is taken. */
3324
+ create(opts: ScheduleOptions): Promise<ScheduleDescription>;
3325
+ /**
3326
+ * Create the schedule, or replace the definition of an existing one (its history — last fire, last
3327
+ * run, fire count — is kept). The next fire is recomputed from now under the new definition, so a
3328
+ * window that already fired is never fired again by an upsert.
3329
+ */
3330
+ upsert(opts: ScheduleOptions): Promise<ScheduleDescription>;
3331
+ /** The schedule `id`, or null. */
3332
+ get(id: string): Promise<ScheduleDescription | null>;
3333
+ /** Schedules matching `query`, soonest-due first. */
3334
+ list(query?: ScheduleListQuery): Promise<ScheduleDescription[]>;
3335
+ /** Delete the schedule. Runs it already started are left alone. Returns whether it existed. */
3336
+ delete(id: string): Promise<boolean>;
3337
+ /** Stop firing until {@link resume}. `note` records why (shown by `get`/`list`). */
3338
+ pause(id: string, note?: string): Promise<ScheduleDescription>;
3339
+ /**
3340
+ * Fire again from the next window after now — the windows skipped while paused are NOT caught up.
3341
+ */
3342
+ resume(id: string): Promise<ScheduleDescription>;
3343
+ /**
3344
+ * Start one run of the schedule right now, outside its cadence (paused or not). The run id is
3345
+ * `sched:<id>:manual:<nowMs>`; it doesn't move the schedule's next fire.
3346
+ */
3347
+ trigger(id: string): Promise<RunResult>;
3348
+ /**
3349
+ * Fire every due schedule (in this engine's namespace; all namespaces for an operator engine):
3350
+ * start its window's run and advance it to the next window. Called by the NestJS timer poller on
3351
+ * each tick when `persistedSchedules` is on; call it yourself from any other driver. Returns the
3352
+ * run ids started (or re-found, for an idempotent re-fire).
3353
+ */
3354
+ tick(nowMs?: number): Promise<string[]>;
3355
+ /** Fire one due schedule and advance it. Returns the run id started, if any. */
3356
+ private fire;
3357
+ /** `overlap: 'skip'` and the previous run of this schedule is still in flight. */
3358
+ private overlapping;
3359
+ private mustGet;
3360
+ private write;
3361
+ }
3362
+
3013
3363
  type WorkflowFn = (ctx: InternalWorkflowCtx, input: unknown) => Promise<unknown>;
3014
3364
  /**
3015
3365
  * Options for {@link WorkflowEngine.start}.
@@ -3055,6 +3405,12 @@ interface StartOptions {
3055
3405
  * maps here), so one DB-less-tenant-facing engine can create runs across many namespaces.
3056
3406
  */
3057
3407
  namespace?: string | undefined;
3408
+ /**
3409
+ * A start-time concurrency quota for this start — at most `limit` runs sharing `key` in flight;
3410
+ * over it, `start` throws {@link ConcurrencyLimitError} and creates nothing. Overrides the
3411
+ * workflow's registered `concurrency`. See {@link ConcurrencyQuota}.
3412
+ */
3413
+ concurrency?: ConcurrencyQuota | undefined;
3058
3414
  }
3059
3415
  /**
3060
3416
  * Serialize runs of a workflow that share a key — a durable, FIFO mutex (e.g. one pipeline per base).
@@ -3305,6 +3661,12 @@ declare class WorkflowEngine {
3305
3661
  private readonly runDispatcher;
3306
3662
  /** Per-key serialization for singleton workflows (admission, back-pressure, notify-on-release). */
3307
3663
  private readonly singletons;
3664
+ /**
3665
+ * Persisted, runtime-managed schedules: create/upsert/pause/resume/delete/list/trigger them, and
3666
+ * `tick()` fires the due ones (the NestJS timer poller does it when `persistedSchedules` is on).
3667
+ * Needs a store that persists schedules — every bundled adapter does. See {@link ScheduleClient}.
3668
+ */
3669
+ readonly schedules: ScheduleClient;
3308
3670
  /** Every registered workflow, keyed by `name@version` — so old versions stay runnable. */
3309
3671
  private readonly workflows;
3310
3672
  /** The newest registered version per workflow name — used to `start` new runs. */
@@ -3380,6 +3742,8 @@ declare class WorkflowEngine {
3380
3742
  register(name: string, version: string, fn: WorkflowFn, opts?: {
3381
3743
  tags?: string[] | undefined;
3382
3744
  singleton?: SingletonConfig | undefined;
3745
+ /** Start-time concurrency quota — see {@link ConcurrencyConfig}. */
3746
+ concurrency?: ConcurrencyConfig | undefined;
3383
3747
  executionTimeout?: string | number | undefined;
3384
3748
  validateInput?: ((input: unknown) => void | Promise<void>) | undefined;
3385
3749
  /** Typed/validated `searchAttributes` shape — see `RegisteredWorkflow.searchAttributesSchema`. */
@@ -3426,6 +3790,7 @@ declare class WorkflowEngine {
3426
3790
  executor: WorkflowExecutor;
3427
3791
  tags?: string[];
3428
3792
  singleton?: SingletonConfig;
3793
+ concurrency?: ConcurrencyConfig;
3429
3794
  executionTimeout?: string | number;
3430
3795
  validateInput?: (input: unknown) => void | Promise<void>;
3431
3796
  /** Capabilities a live worker must advertise to run this remote workflow's turns (handshake §7.5). */
@@ -3451,6 +3816,7 @@ declare class WorkflowEngine {
3451
3816
  version?: string;
3452
3817
  tags?: string[];
3453
3818
  singleton?: SingletonConfig;
3819
+ concurrency?: ConcurrencyConfig;
3454
3820
  executionTimeout?: string | number;
3455
3821
  validateInput?: (input: unknown) => void | Promise<void>;
3456
3822
  /** Capabilities a live worker must advertise to run this workflow's turns (handshake §7.5). */
@@ -3878,6 +4244,43 @@ declare class WorkflowEngine {
3878
4244
  * its worker (its next checkpoint write fails). Returns the number of runs deleted (0 if absent).
3879
4245
  */
3880
4246
  deleteRun(runId: string): Promise<number>;
4247
+ /**
4248
+ * Hard-delete EVERY run matching `scope` — plus, by default, each one's whole child subtree — in
4249
+ * bounded batches. The "forget this tenant" / "drop this feature's history" operation: where
4250
+ * {@link deleteRun} removes one tree you already know the id of, this drains everything a scope
4251
+ * selects (`{ namespace: 'acme' }`, `{ tag: 'tenant:acme' }`, `{ workflows: [...] }`, attribute
4252
+ * predicates …) through the store API, so no caller has to reach into the `durable_*` tables.
4253
+ *
4254
+ * - **Live runs** (not yet terminal) are {@link cancel cancelled} first (plain cancel, no saga
4255
+ * undo), which tells any worker holding one to stop, and then deleted with the rest. Pass
4256
+ * `cancelLive: false` to leave live runs (and live descendants of finished ones) alone and
4257
+ * delete terminal history only.
4258
+ * - **Children** are found through the same parent→child edges as {@link getRunChildren} and deleted
4259
+ * with their root even when they don't match `scope` themselves (children inherit `namespace`,
4260
+ * but not `tags`). `children: false` deletes exactly the matching runs.
4261
+ * - **Batched**: `batchSize` runs (default 500) per round, each round one bulk
4262
+ * {@link StateStore.deleteRuns} (falling back to per-run {@link StateStore.deleteRun}).
4263
+ *
4264
+ * An EMPTY scope is rejected — it would delete every run in the store. Returns how many runs were
4265
+ * deleted (children included).
4266
+ */
4267
+ purgeRuns(scope: RunScope, opts?: {
4268
+ batchSize?: number;
4269
+ cancelLive?: boolean;
4270
+ children?: boolean;
4271
+ }): Promise<number>;
4272
+ /**
4273
+ * {@link purgeRuns} for one namespace — every run (and child) a tenant/partition owns. Children
4274
+ * inherit their parent's namespace, so a namespace purge is complete by construction.
4275
+ */
4276
+ purgeNamespace(namespace: string, opts?: {
4277
+ batchSize?: number;
4278
+ cancelLive?: boolean;
4279
+ }): Promise<number>;
4280
+ /** The given runs plus every descendant, children before parents. One waiter scan for the batch. */
4281
+ private collectSubtrees;
4282
+ /** Bulk-delete through the store's `deleteRuns`, or one `deleteRun` per id when it has none. */
4283
+ private deleteRunIds;
3881
4284
  /**
3882
4285
  * Cascade cancellation to a run's children — both awaited (`ctx.child`, found via its live
3883
4286
  * `child:<id>` waiter) and fire-and-forget (`ctx.startChild`, found via its `spawn:<id>`
@@ -4400,6 +4803,19 @@ declare class FatalError extends Error {
4400
4803
  readonly code?: string | undefined;
4401
4804
  constructor(message: string, code?: string);
4402
4805
  }
4806
+ /**
4807
+ * Thrown by `start` when a run would exceed its concurrency quota: `active` runs sharing the quota
4808
+ * `key` are already in flight (in the quota's counted statuses) and the `limit` is `limit`. Nothing
4809
+ * was created — the start is rejected up front, so the caller can shed load or answer "try again in a
4810
+ * moment" (e.g. map it to HTTP 429). See `StartOptions.concurrency` / `ConcurrencyConfig`.
4811
+ */
4812
+ declare class ConcurrencyLimitError extends Error {
4813
+ readonly workflow: string;
4814
+ readonly key: string;
4815
+ readonly limit: number;
4816
+ readonly active: number;
4817
+ constructor(workflow: string, key: string, limit: number, active: number);
4818
+ }
4403
4819
  /**
4404
4820
  * Thrown by `start` when a singleton workflow's wait queue is full: the count of in-flight + gated
4405
4821
  * runs sharing the key already equals `limit + maxQueueDepth`, so admitting another would let the
@@ -4660,7 +5076,7 @@ declare const RUN_VALUE_FACET_SCAN = 5000;
4660
5076
  * sets exactly that), so it stays offered — just after the tags a human wrote. `version:undeclared`
4661
5077
  * is engine-minted too but is a single fixed value, so it competes fairly and is not listed here.
4662
5078
  */
4663
- declare const ENGINE_MINTED_TAG_PREFIXES: readonly ["singleton:"];
5079
+ declare const ENGINE_MINTED_TAG_PREFIXES: readonly ["singleton:", "concurrency:"];
4664
5080
  /** Is this a tag the engine mints one of per key? See {@link ENGINE_MINTED_TAG_PREFIXES}. */
4665
5081
  declare function isEngineMintedTag(value: string | null): boolean;
4666
5082
  /**
@@ -4863,6 +5279,22 @@ declare class CodecStateStore implements StateStore {
4863
5279
  * Bound the same conditional way as {@link runFacets} so absence is reported, not faked.
4864
5280
  */
4865
5281
  readonly runValueFacets?: (axis: RunValueAxis, query: RunFacetQuery, opts?: RunValueFacetOptions) => Promise<RunValueFacetRow[]>;
5282
+ /** Forwarded verbatim (deletes touch no payload). Bound only when the inner store has it, so the
5283
+ * engine's per-run fallback still kicks in through the wrapper. */
5284
+ readonly deleteRuns?: (runIds: string[]) => Promise<void>;
5285
+ /** Forwarded verbatim — retention selects by status/updatedAt/scope, never by payload. Bound only
5286
+ * when the inner store prunes, so the retention poller still sees (and warns about) its absence. */
5287
+ readonly pruneTerminalRuns?: (policy: RetentionPolicy, nowMs: number, limit: number) => Promise<number>;
5288
+ /** Forwarded verbatim — a count reads no payload. Bound only when the inner store counts, so the
5289
+ * engine's facet/listing fallback still applies through the wrapper. */
5290
+ readonly countRuns?: (query: Omit<RunQuery, 'limit' | 'offset'>) => Promise<number>;
5291
+ /** Schedules persist their run `input` inside `spec` — encoded like any other payload. Bound only
5292
+ * when the inner store persists schedules, so `engine.schedules` reports absence faithfully. */
5293
+ readonly saveSchedule?: (record: ScheduleRecord) => Promise<void>;
5294
+ readonly getSchedule?: (id: string) => Promise<ScheduleRecord | null>;
5295
+ readonly updateSchedule?: (id: string, patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>, expectedNextFireAt?: number | null) => Promise<boolean>;
5296
+ readonly deleteSchedule?: (id: string) => Promise<boolean>;
5297
+ readonly listSchedules?: (query: ScheduleQuery) => Promise<ScheduleRecord[]>;
4866
5298
  constructor(inner: StateStore, codec: PayloadCodec);
4867
5299
  private enc;
4868
5300
  private dec;
@@ -4870,6 +5302,9 @@ declare class CodecStateStore implements StateStore {
4870
5302
  private decRun;
4871
5303
  private encCp;
4872
5304
  private decCp;
5305
+ private encSpec;
5306
+ private encSchedule;
5307
+ private decSchedule;
4873
5308
  ensureSchema(): Promise<void>;
4874
5309
  createRun(run: WorkflowRun): Promise<void>;
4875
5310
  updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void>;
@@ -5039,6 +5474,12 @@ declare function scheduledRunId(key: string, everyMs: number, nowMs: number): st
5039
5474
  * interval resolves to the same fire time — and thus the same idempotent run id.
5040
5475
  */
5041
5476
  declare function prevCronFireMs(expr: string, nowMs: number, timezone?: string): number;
5477
+ /**
5478
+ * Epoch ms of the first cron fire STRICTLY after `afterMs`, evaluated in `timezone` (default UTC) —
5479
+ * the forward counterpart of {@link prevCronFireMs}, used by persisted schedules to compute when a
5480
+ * schedule is next due.
5481
+ */
5482
+ declare function nextCronFireMs(expr: string, afterMs: number, timezone?: string): number;
5042
5483
  /**
5043
5484
  * Start each schedule's current-window run. The run id is the time bucket (a fixed-interval index,
5044
5485
  * or the cron fire time) and `engine.start` is idempotent, so firing this on an interval — or
@@ -5297,6 +5738,8 @@ declare class InMemoryStateStore implements StateStore {
5297
5738
  updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void>;
5298
5739
  getRun(runId: string): Promise<WorkflowRun | null>;
5299
5740
  deleteRun(runId: string): Promise<void>;
5741
+ deleteRuns(runIds: string[]): Promise<void>;
5742
+ pruneTerminalRuns(policy: RetentionPolicy, nowMs: number, limit: number): Promise<number>;
5300
5743
  getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null>;
5301
5744
  saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
5302
5745
  listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
@@ -5343,11 +5786,18 @@ declare class InMemoryStateStore implements StateStore {
5343
5786
  * {@link listRuns} (which then sorts + pages it) and {@link runFacets} (which groups it). */
5344
5787
  private matching;
5345
5788
  listRuns(query: RunQuery): Promise<WorkflowRun[]>;
5789
+ countRuns(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number>;
5346
5790
  runFacets(query: RunFacetQuery): Promise<RunFacetRow[]>;
5347
5791
  /** Counted over the newest `scan` matching runs for EVERY axis, not just `tag`: this store holds
5348
5792
  * its runs in a Map with no index to group by, so the bound that the SQL stores need only for tags
5349
5793
  * is the honest one to apply here throughout. */
5350
5794
  runValueFacets(axis: RunValueAxis, query: RunFacetQuery, opts?: RunValueFacetOptions): Promise<RunValueFacetRow[]>;
5795
+ private readonly schedules;
5796
+ saveSchedule(record: ScheduleRecord): Promise<void>;
5797
+ getSchedule(id: string): Promise<ScheduleRecord | null>;
5798
+ updateSchedule(id: string, patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>, expectedNextFireAt?: number | null): Promise<boolean>;
5799
+ deleteSchedule(id: string): Promise<boolean>;
5800
+ listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]>;
5351
5801
  listCheckpoints(runId: string): Promise<StepCheckpoint[]>;
5352
5802
  getLatestCheckpointByName(runId: string, name: string): Promise<StepCheckpoint | undefined>;
5353
5803
  listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]>;
@@ -5379,4 +5829,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
5379
5829
  onControl(handler: (msg: ControlMessage) => void): void;
5380
5830
  }
5381
5831
 
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 };
5832
+ 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, 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 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, 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, runInWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };