@dudousxd/nestjs-durable 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.cjs +791 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +417 -0
  5. package/dist/index.d.ts +417 -8
  6. package/dist/index.js +745 -21
  7. package/dist/index.js.map +1 -1
  8. package/package.json +21 -7
  9. package/dist/context-accessor.d.ts +0 -31
  10. package/dist/context-accessor.d.ts.map +0 -1
  11. package/dist/context-accessor.js +0 -3
  12. package/dist/context-accessor.js.map +0 -1
  13. package/dist/decorators.d.ts +0 -146
  14. package/dist/decorators.d.ts.map +0 -1
  15. package/dist/decorators.js +0 -103
  16. package/dist/decorators.js.map +0 -1
  17. package/dist/durable-step.registrar.d.ts +0 -30
  18. package/dist/durable-step.registrar.d.ts.map +0 -1
  19. package/dist/durable-step.registrar.js +0 -85
  20. package/dist/durable-step.registrar.js.map +0 -1
  21. package/dist/durable.module.d.ts +0 -108
  22. package/dist/durable.module.d.ts.map +0 -1
  23. package/dist/durable.module.js +0 -207
  24. package/dist/durable.module.js.map +0 -1
  25. package/dist/entity.d.ts +0 -43
  26. package/dist/entity.d.ts.map +0 -1
  27. package/dist/entity.js +0 -94
  28. package/dist/entity.js.map +0 -1
  29. package/dist/index.d.ts.map +0 -1
  30. package/dist/input-validation.d.ts +0 -9
  31. package/dist/input-validation.d.ts.map +0 -1
  32. package/dist/input-validation.js +0 -30
  33. package/dist/input-validation.js.map +0 -1
  34. package/dist/step-interceptor.d.ts +0 -20
  35. package/dist/step-interceptor.d.ts.map +0 -1
  36. package/dist/step-interceptor.js +0 -22
  37. package/dist/step-interceptor.js.map +0 -1
  38. package/dist/timer-poller.d.ts +0 -20
  39. package/dist/timer-poller.d.ts.map +0 -1
  40. package/dist/timer-poller.js +0 -81
  41. package/dist/timer-poller.js.map +0 -1
  42. package/dist/tokens.d.ts +0 -13
  43. package/dist/tokens.d.ts.map +0 -1
  44. package/dist/tokens.js +0 -16
  45. package/dist/tokens.js.map +0 -1
  46. package/dist/workflow.registrar.d.ts +0 -33
  47. package/dist/workflow.registrar.d.ts.map +0 -1
  48. package/dist/workflow.registrar.js +0 -169
  49. package/dist/workflow.registrar.js.map +0 -1
  50. package/dist/workflow.service.d.ts +0 -55
  51. package/dist/workflow.service.d.ts.map +0 -1
  52. package/dist/workflow.service.js +0 -58
  53. package/dist/workflow.service.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,8 +1,417 @@
1
- export * from './context-accessor';
2
- export * from './decorators';
3
- export * from './durable.module';
4
- export * from './entity';
5
- export * from './step-interceptor';
6
- export * from './tokens';
7
- export * from './workflow.service';
8
- //# sourceMappingURL=index.d.ts.map
1
+ import { StepError, WorkflowRef, SingletonConfig, StateStore, Transport, NamedTransport, ControlPlane, ScheduledWorkflow, QueueConfig, AdmissionBackend, WorkflowEngine, EntityHandler, StepInvocation, WorkflowClass, WorkflowInputOf, StartOptions, RunResult } from '@dudousxd/nestjs-durable-core';
2
+ import { DynamicModule, InjectionToken } from '@nestjs/common';
3
+
4
+ /**
5
+ * Local, structural mirror of `@dudousxd/nestjs-context`'s public accessor
6
+ * (`packages/core/src/accessor.ts`).
7
+ *
8
+ * We deliberately do NOT import nestjs-context (it is an OPTIONAL peer). Instead
9
+ * we declare the same shape here and inject it via the shared
10
+ * {@link CONTEXT_ACCESSOR} token with `@Optional()`. Any object that structurally
11
+ * satisfies this interface — including nestjs-context's real accessor — works.
12
+ *
13
+ * Kept byte-aligned with nestjs-context's `ContextAccessor` (and the identical
14
+ * mirror in `@dudousxd/nestjs-authz`): `traceId()` / `tenantId()` are REQUIRED
15
+ * (the real accessor always provides them) and `get()` is included, so the
16
+ * structural match stays exact when DurableModule auto-feeds the carrier.
17
+ */
18
+ interface UserRef {
19
+ type: string;
20
+ id: string | number;
21
+ }
22
+ /** Opaque shape of the context store. durable never reads it; mirrors the upstream surface. */
23
+ type ContextStore = Record<string, unknown>;
24
+ interface ContextAccessor {
25
+ /** Trace id for the current request, or `undefined` when unavailable. */
26
+ traceId(): string | undefined;
27
+ /** Current tenant id, or `undefined` when no multi-tenant context is populated. */
28
+ tenantId(): string | undefined;
29
+ /** Reference to the current user, or `undefined` when unauthenticated. */
30
+ userRef(): UserRef | undefined;
31
+ /** The raw context store for the current request, or `undefined`. */
32
+ get(): ContextStore | undefined;
33
+ }
34
+
35
+ declare const WORKFLOW_METADATA: unique symbol;
36
+ interface WorkflowMeta {
37
+ name: string;
38
+ version: string;
39
+ /** The workflow this workflow's dead runs route to (a name or a class). See `WorkflowOptions`. */
40
+ deadLetterWorkflow?: WorkflowRef | undefined;
41
+ /** Static searchable labels stamped on every run of this workflow. See `WorkflowOptions`. */
42
+ tags?: string[] | undefined;
43
+ /** Per-key serialization (a durable mutex). See `WorkflowOptions`. */
44
+ singleton?: SingletonConfig | undefined;
45
+ /** Max wall-clock lifetime before a run is cancelled (e.g. `'2h'`). See `WorkflowOptions`. */
46
+ executionTimeout?: string | number | undefined;
47
+ /** class-validator DTO validated at start. See `WorkflowOptions`. */
48
+ inputSchema?: (new (...args: any[]) => object) | undefined;
49
+ /** Custom input validator (throws on invalid). See `WorkflowOptions`. */
50
+ validateInput?: ((input: unknown) => void | Promise<void>) | undefined;
51
+ /** Event names that start a fresh run of this workflow. See `WorkflowOptions`. */
52
+ onEvent?: string[] | undefined;
53
+ /** Debounce `onEvent` triggers — fire once it's quiet for this long. See `WorkflowOptions`. */
54
+ debounce?: string | number | undefined;
55
+ /** Batch `onEvent` triggers — fire on size or window. See `WorkflowOptions`. */
56
+ batch?: {
57
+ maxSize: number;
58
+ within: string | number;
59
+ } | undefined;
60
+ }
61
+ interface WorkflowOptions {
62
+ name: string;
63
+ version?: string;
64
+ /**
65
+ * Route this workflow's dead-lettered runs to another **registered** workflow — by class
66
+ * (`deadLetterWorkflow: CheckoutDlqWorkflow`, refactor-safe) or by name for a cross-runtime
67
+ * handler. For a handler co-located on the same class, prefer an inline `@DeadLetter()` method
68
+ * instead — it takes precedence, and declaring both is a boot-time error. The handler receives a
69
+ * {@link DeadLetter} payload, idempotent by a `dlq:<runId>` id.
70
+ */
71
+ deadLetterWorkflow?: WorkflowRef;
72
+ /**
73
+ * Static labels stamped on **every run** of this workflow (e.g. `tags: ['etl', 'critical']`) and
74
+ * merged with any per-run tags passed to `start`. Searchable/filterable in the dashboard.
75
+ */
76
+ tags?: string[];
77
+ /**
78
+ * Serialize runs of this workflow that share a key — a durable FIFO mutex. e.g.
79
+ * `singleton: { key: (input) => `base:${input.baseId}` }` runs at most one pipeline per base at a
80
+ * time; same-key runs queue (suspended) and admit in creation order as slots free. `limit` (default
81
+ * 1) raises the concurrency.
82
+ */
83
+ singleton?: SingletonConfig;
84
+ /**
85
+ * Max wall-clock lifetime for a run of this workflow (e.g. `'2h'`, `'7 days'`, or ms). A run that
86
+ * outlives it is moved to `cancelled` (`execution_timeout`) by the timer poller — a backstop for
87
+ * runs that get stuck or loop forever. Omit for no limit.
88
+ */
89
+ executionTimeout?: string | number;
90
+ /**
91
+ * Validate the workflow input at `start` against a **class-validator DTO** (the same
92
+ * `plainToInstance` + `validate` NestJS runs in controllers) — invalid input is rejected before any
93
+ * run is created. Needs the optional peers `class-validator` + `class-transformer`.
94
+ * `@Workflow({ inputSchema: CheckoutInput })`.
95
+ */
96
+ inputSchema?: new (...args: any[]) => object;
97
+ /**
98
+ * Custom input validator (throws on invalid) — an escape hatch for zod/yup/etc. instead of
99
+ * `inputSchema`. Takes precedence over `inputSchema` if both are set.
100
+ */
101
+ validateInput?: (input: unknown) => void | Promise<void>;
102
+ /**
103
+ * Start a fresh run of this workflow whenever any of these events is published via
104
+ * `publishEvent(name, payload)` — the payload becomes the run's input. e.g.
105
+ * `onEvent: ['user.registered', 'user.invited']`. The same subscription can also be declared with
106
+ * the `@OnEvent(...)` class decorator; the two are merged.
107
+ */
108
+ onEvent?: string[];
109
+ /**
110
+ * Coalesce `onEvent` triggers by **debouncing** — start one run only once events have been quiet
111
+ * for this long (resets on each event), with the LAST payload. e.g. `debounce: '30s'`.
112
+ */
113
+ debounce?: string | number;
114
+ /**
115
+ * Coalesce `onEvent` triggers by **batching** — start one run with all payloads (`{ events: [...] }`)
116
+ * once `maxSize` is reached or `within` elapses from the first event. e.g.
117
+ * `batch: { maxSize: 100, within: '10s' }`.
118
+ */
119
+ batch?: {
120
+ maxSize: number;
121
+ within: string | number;
122
+ };
123
+ }
124
+ /**
125
+ * Marks a provider class as a durable workflow. Its `run(ctx, input)` method becomes the
126
+ * workflow function the engine executes and replays.
127
+ */
128
+ declare function Workflow(options: WorkflowOptions): ClassDecorator;
129
+ declare function getWorkflowMeta(target: Function): WorkflowMeta | undefined;
130
+ declare const DURABLE_STEP_METADATA: unique symbol;
131
+ interface DurableStepMeta {
132
+ name: string;
133
+ }
134
+ /**
135
+ * Marks a provider method as the handler for a remote step `name`. An in-process transport
136
+ * (e.g. the event-emitter transport) routes dispatched tasks to it. The method's single
137
+ * argument is the step input; its return value is the step output.
138
+ */
139
+ declare function DurableStep(name: string): MethodDecorator;
140
+ declare function getDurableStepMeta(method: Function): DurableStepMeta | undefined;
141
+ declare const DEAD_LETTER_METADATA: unique symbol;
142
+ /**
143
+ * The payload a dead-letter handler receives: the dead run's id, its workflow, the input it was
144
+ * started with (typed via `TInput`), and the failure that killed it.
145
+ */
146
+ interface DeadLetter<TInput = unknown> {
147
+ /** Id of the run that was dead-lettered (inspectable + retriable in the dashboard). */
148
+ deadRunId: string;
149
+ /** Name of the workflow whose run died. */
150
+ workflow: string;
151
+ /** The original input the dead run was started with. */
152
+ input: TInput;
153
+ /** The structured error that moved the run to `dead`, when known. */
154
+ error?: StepError;
155
+ }
156
+ /**
157
+ * Marks a method on a `@Workflow` class as that workflow's **inline dead-letter handler**. When a
158
+ * run of the workflow is moved to `dead` (exceeded `maxRecoveryAttempts`), this method runs — as a
159
+ * durable workflow itself, auto-registered as `<workflow>.dlq` with a `dlq:<runId>` id — receiving a
160
+ * {@link DeadLetter} payload. It shares the class's injected dependencies, so the handler lives in
161
+ * the same file as the workflow it protects.
162
+ *
163
+ * Takes precedence over `@Workflow({ deadLetterWorkflow })` and the module-level `deadLetterWorkflow`
164
+ * default. The method signature is `(ctx, dead)` — the same `ctx` a workflow `run` gets.
165
+ */
166
+ declare function DeadLetter(): MethodDecorator;
167
+ declare function isDeadLetterHandler(method: Function): boolean;
168
+ declare const ON_EVENT_METADATA: unique symbol;
169
+ /**
170
+ * Subscribe a `@Workflow` class to one or more events: when any of them is published via
171
+ * `publishEvent(name, payload)`, a fresh run of the workflow starts with the payload as input.
172
+ * Equivalent to `@Workflow({ onEvent })` — use whichever reads better; multiple `@OnEvent(...)`
173
+ * decorators and the option are all merged.
174
+ */
175
+ declare function OnEvent(...events: string[]): ClassDecorator;
176
+ /** All events a workflow class subscribes to — the union of `@Workflow({ onEvent })` and `@OnEvent`. */
177
+ declare function getOnEvents(meta: WorkflowMeta, target: object): string[];
178
+
179
+ interface DurableModuleOptions {
180
+ store: StateStore;
181
+ transport?: Transport;
182
+ /**
183
+ * An ordered pool of named transports for failover / multi-broker setups. The engine dispatches on
184
+ * the first and fails over to the next; a step pins one via `ctx.call(step, input, { transport })`.
185
+ * Use instead of `transport`.
186
+ */
187
+ transports?: NamedTransport[];
188
+ /**
189
+ * Cross-instance broadcast pub/sub (lifecycle events + cancellation). Defaults to the (first)
190
+ * transport when it can broadcast (event-emitter, BullMQ); set explicitly to use a dedicated one.
191
+ */
192
+ controlPlane?: ControlPlane;
193
+ /** Interval (ms) for the durable-timer poller. `0` disables it. Defaults to 1000. */
194
+ timerPollMs?: number;
195
+ /**
196
+ * Auto-create the durable tables on boot via `store.ensureSchema()`. Defaults to true. Turn
197
+ * off in production and call the store adapter's `ensure*DurableSchema()` from a migration.
198
+ */
199
+ autoSchema?: boolean;
200
+ /**
201
+ * Multi-instance recovery lease, in ms — how long an instance owns a run it picked up before
202
+ * another may take over. Defaults to 30000. Set above your longest synchronous run.
203
+ */
204
+ leaseMs?: number;
205
+ /** Unique id for this instance (for leases). Defaults to a random id. */
206
+ instanceId?: string;
207
+ /**
208
+ * Cap recovery attempts before a still-`running` run is moved to the `dead` dead-letter state
209
+ * (a poison pill that crashes the process every boot). Omit for unlimited.
210
+ */
211
+ maxRecoveryAttempts?: number;
212
+ /**
213
+ * The **default** workflow to route dead-lettered runs to, for workflows that don't declare their
214
+ * own. When a run is moved to `dead` (exceeded `maxRecoveryAttempts`), the started handler gets a
215
+ * `DeadLetter` payload `{ deadRunId, workflow, input, error }` (idempotent by a `dlq:<runId>` id) —
216
+ * it can alert, compensate, or queue for review. Resolution per dead run: the workflow's inline
217
+ * `@DeadLetter()` method → its `@Workflow({ deadLetterWorkflow })` reference → this default. Omit
218
+ * everything to just leave dead runs parked (inspectable + retriable from the dashboard). Accepts a
219
+ * workflow class (refactor-safe) or a name (cross-runtime).
220
+ */
221
+ deadLetterWorkflow?: WorkflowRef;
222
+ /**
223
+ * Whether this instance plays the **worker** role: register `@DurableStep` handlers (consume the
224
+ * transport), recover incomplete runs on boot, and poll due timers. Defaults to `true`. Set
225
+ * `false` for a **dashboard/dispatch-only** instance (e.g. an API pod) that mounts the control
226
+ * plane and reads the store but must not process or recover workflows — leave that to the workers.
227
+ */
228
+ worker?: boolean;
229
+ /** Max ms to wait for in-flight runs on shutdown before exiting. Defaults to 10000. */
230
+ shutdownTimeoutMs?: number;
231
+ /**
232
+ * Recurring workflows to start on a schedule (fixed interval or cron). The timer poller fires
233
+ * them each tick on **worker** instances only; `engine.start` is idempotent by the schedule's
234
+ * time-bucket run id, so racing instances start each window exactly once. Cron schedules need the
235
+ * optional `cron-parser` peer dependency.
236
+ */
237
+ schedules?: ScheduledWorkflow[];
238
+ /**
239
+ * Build the public callback URL for a `ctx.webhook()` token, e.g.
240
+ * ``(t) => `https://api.example.com/durable/api/webhooks/${t}` ``. Populates `DurableWebhook.url`
241
+ * so a step can hand the URL to a third party. The dashboard's `POST webhooks/:token` receives the
242
+ * callback. Omit to build URLs yourself from the token.
243
+ */
244
+ webhookUrl?: (token: string) => string;
245
+ /**
246
+ * Flow-control queues for remote steps, registered on the engine at startup. Reference one from a
247
+ * workflow with `ctx.call(step, input, { queue: name })` to cap its concurrency / admission rate.
248
+ */
249
+ queues?: QueueConfig[];
250
+ /**
251
+ * Admission backend for the flow-control `queues`. Defaults to in-process (per-instance) caps. Pass
252
+ * a `RedisAdmissionBackend` (from `@dudousxd/nestjs-durable-admission-redis`) to make concurrency /
253
+ * rate-limit / priority ordering GLOBAL across every engine replica.
254
+ */
255
+ admission?: AdmissionBackend;
256
+ /**
257
+ * Provide the current W3C `traceparent` to stamp on dispatched remote tasks, so workers continue
258
+ * the distributed trace. Pass `otelTraceparent` from `@dudousxd/nestjs-durable-otel`.
259
+ */
260
+ traceparent?: () => string | undefined;
261
+ /**
262
+ * Provide an opaque context carrier (tenant / user / correlation ids) to stamp on dispatched remote
263
+ * tasks, so workers re-expose it to the step handler alongside the `traceparent`. The engine never
264
+ * inspects its shape.
265
+ *
266
+ * **Auto-feed**: if you omit this AND `@dudousxd/nestjs-context` is installed (its accessor is bound
267
+ * to the shared `CONTEXT_ACCESSOR` token), DurableModule defaults this to a reader that builds
268
+ * `{ traceId, tenantId, userRef }` from the accessor — so a workflow dispatched within a request
269
+ * automatically carries the originating context across process boundaries. Pass your own reader to
270
+ * override the auto-feed; with neither, the carrier is omitted (unchanged behavior).
271
+ *
272
+ * Re-evaluated at each (re)dispatch — including a retry or a crash/scale-down resume that the engine
273
+ * drives OUTSIDE the originating request scope, where this reader may return empty or stale values.
274
+ * Treat the carrier as best-effort correlation/propagation metadata only — do NOT treat it as an
275
+ * authorization boundary.
276
+ */
277
+ context?: () => Record<string, unknown> | undefined;
278
+ /** Attempts for each saga compensation when a run fails. Default 1 (no retry). Idempotent undos. */
279
+ compensationRetries?: number;
280
+ }
281
+ interface DurableModuleAsyncOptions {
282
+ useFactory: (...args: never[]) => DurableModuleOptions | Promise<DurableModuleOptions>;
283
+ inject?: InjectionToken[];
284
+ }
285
+ declare class DurableModule {
286
+ static forRoot(options: DurableModuleOptions): DynamicModule;
287
+ static forRootAsync(options: DurableModuleAsyncOptions): DynamicModule;
288
+ private static build;
289
+ }
290
+
291
+ declare const ENTITY_METADATA: unique symbol;
292
+ declare const ENTITY_ON_METADATA: unique symbol;
293
+ /**
294
+ * Marks an `@Injectable()` class as a **durable entity** (a virtual object): its `@On(op)` methods run
295
+ * serialized per key over the instance's fields as durable state. e.g.
296
+ *
297
+ * ```ts
298
+ * @Entity({ name: 'cart' }) @Injectable()
299
+ * class Cart { items: Item[] = []; @On('add') add(i: Item) { this.items.push(i); } @On('list') list() { return this.items; } }
300
+ * ```
301
+ *
302
+ * The class must be **constructible with no arguments** (a fresh instance is the initial state per key)
303
+ * — keep entities pure state, no DI. Drive them with `EntityService` or `ctx.signalEntity`/`callEntity`.
304
+ */
305
+ declare function Entity(options: {
306
+ name: string;
307
+ }): ClassDecorator;
308
+ /** Marks an entity method as the handler for operation `op`. */
309
+ declare function On(op: string): MethodDecorator;
310
+ declare function getEntityMeta(target: Function): {
311
+ name: string;
312
+ } | undefined;
313
+ /**
314
+ * Build the engine `EntityConfig` for a discovered `@Entity` class: a fresh instance per key, and
315
+ * handlers that rehydrate the class prototype onto the (serialized) state before dispatching the op,
316
+ * so methods work after replay.
317
+ */
318
+ declare function entityConfigFor(ctor: Function): {
319
+ initialState: () => object;
320
+ handlers: Record<string, EntityHandler>;
321
+ };
322
+ /** Inject this to drive durable entities from outside a workflow. */
323
+ declare class EntityService {
324
+ private readonly engine;
325
+ constructor(engine: WorkflowEngine);
326
+ /** Send an operation to an entity (fire-and-forget; ordered + exactly-once per key). */
327
+ signal(name: string, key: string, op: string, arg?: unknown): Promise<void>;
328
+ /** Read an entity's current durable state (or undefined if it has none yet). */
329
+ getState<S = unknown>(name: string, key: string): Promise<S | undefined>;
330
+ }
331
+
332
+ declare const STEP_INTERCEPTOR_METADATA: unique symbol;
333
+ /**
334
+ * The shape a `@StepInterceptor()` provider must implement: `intercept(invocation, next)` wraps the
335
+ * real execution of every local `ctx.step` (call `next()` to run the step body / next interceptor,
336
+ * and return — or transform — its result). The engine-level {@link StepInterceptor} primitive, with
337
+ * NestJS dependency injection.
338
+ */
339
+ interface DurableStepInterceptor {
340
+ intercept(invocation: StepInvocation, next: () => Promise<unknown>): Promise<unknown>;
341
+ }
342
+ /**
343
+ * Marks an `@Injectable()` class as a durable step interceptor. The module discovers it on boot and
344
+ * registers its `intercept` method with the engine (so it can inject loggers/tracers/etc.). First
345
+ * declared is outermost. Interceptors fire only when a step actually executes, never on replay.
346
+ */
347
+ declare function StepInterceptor(): ClassDecorator;
348
+ declare function isStepInterceptor(target: Function): boolean;
349
+
350
+ /**
351
+ * Cross-lib injection token for the current-request context accessor, owned by
352
+ * `@dudousxd/nestjs-context`. We do NOT import nestjs-context (it is an OPTIONAL
353
+ * peer dependency) — instead we share its well-known token by value so DI
354
+ * resolves the same provider when nestjs-context is installed and present.
355
+ *
356
+ * `Symbol.for(key)` uses the global symbol registry, so this resolves to the
357
+ * SAME symbol instance as nestjs-context's `tokens.ts` (and the identical token
358
+ * declared by `@dudousxd/nestjs-authz`) without any import. The key MUST stay
359
+ * byte-identical with nestjs-context's export.
360
+ */
361
+ declare const CONTEXT_ACCESSOR: unique symbol;
362
+
363
+ /** Public entry point for starting and resuming workflow runs. */
364
+ declare class WorkflowService {
365
+ private readonly engine;
366
+ constructor(engine: WorkflowEngine);
367
+ /**
368
+ * Enqueue a workflow run — it creates the run (`pending`) and returns `{ runId, status: 'pending' }`
369
+ * immediately; a worker executes the body (so the caller never blocks on workflow logic). Use
370
+ * {@link waitForRun} when you need the outcome. Pass the workflow's **class**
371
+ * (`start(CheckoutWorkflow, input)`) for a typed input + refactor-safety, or a **name** string for a
372
+ * cross-runtime workflow. `runId` defaults to a random id; pass your own to make the start idempotent
373
+ * (a redelivery returns the existing run). `opts.tags` are merged with the workflow's static
374
+ * `@Workflow({ tags })`; `opts.searchAttributes` stamp typed, queryable run data.
375
+ */
376
+ start<C extends WorkflowClass>(workflow: C, input: WorkflowInputOf<C>, runId?: string, opts?: StartOptions): Promise<RunResult>;
377
+ start(workflow: string, input: unknown, runId?: string, opts?: StartOptions): Promise<RunResult>;
378
+ resume(runId: string): Promise<RunResult>;
379
+ /**
380
+ * Resolve once a run settles — terminal (completed/failed/cancelled/dead) or suspended. `start`
381
+ * only enqueues (a worker runs the body), so pair them when a request needs the outcome:
382
+ * `const { runId } = await svc.start(...); const result = await svc.waitForRun(runId)`.
383
+ */
384
+ waitForRun(runId: string, opts?: {
385
+ timeoutMs?: number;
386
+ }): Promise<RunResult>;
387
+ /** Deliver an external signal (e.g. from a webhook) to the run waiting on `token`. */
388
+ signal(token: string, payload: unknown): Promise<RunResult | null>;
389
+ /**
390
+ * Ensure a run exists for `runId`, then deliver a signal to it — race-free (the signal is buffered
391
+ * until the run reaches its `waitForSignal`). The durable-entity / accumulator pattern: one
392
+ * long-lived run per key fed events by many calls. See {@link WorkflowEngine.signalWithStart}.
393
+ */
394
+ signalWithStart<C extends WorkflowClass>(workflow: C, input: WorkflowInputOf<C>, runId: string, signal: {
395
+ token: string;
396
+ payload?: unknown;
397
+ }, opts?: StartOptions): Promise<{
398
+ runId: string;
399
+ }>;
400
+ signalWithStart(workflow: string, input: unknown, runId: string, signal: {
401
+ token: string;
402
+ payload?: unknown;
403
+ }, opts?: StartOptions): Promise<{
404
+ runId: string;
405
+ }>;
406
+ /**
407
+ * Publish a named event. Resumes runs waiting on it via `ctx.waitForEvent(name, { match })` and
408
+ * starts a fresh run of every workflow subscribed via `@Workflow({ onEvent })` / `@OnEvent` (the
409
+ * payload becomes its input). Pass `opts.id` to dedupe redeliveries. Returns how many runs it
410
+ * touched (resumed + started).
411
+ */
412
+ publishEvent(name: string, payload: unknown, opts?: {
413
+ id?: string;
414
+ }): Promise<number>;
415
+ }
416
+
417
+ export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, DEAD_LETTER_METADATA, DURABLE_STEP_METADATA, DeadLetter, DurableModule, type DurableModuleAsyncOptions, type DurableModuleOptions, DurableStep, type DurableStepInterceptor, type DurableStepMeta, ENTITY_METADATA, ENTITY_ON_METADATA, Entity, EntityService, ON_EVENT_METADATA, On, OnEvent, STEP_INTERCEPTOR_METADATA, StepInterceptor, type UserRef, WORKFLOW_METADATA, Workflow, type WorkflowMeta, type WorkflowOptions, WorkflowService, entityConfigFor, getDurableStepMeta, getEntityMeta, getOnEvents, getWorkflowMeta, isDeadLetterHandler, isStepInterceptor };