@dudousxd/nestjs-durable 0.47.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +524 -283
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -5
- package/dist/index.d.ts +106 -5
- package/dist/index.js +437 -200
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
- package/skills/durable-setup/SKILL.md +6 -0
- package/skills/durable-workflows/SKILL.md +67 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { WorkflowCtx, SearchAttributes, WorkflowClass, StepError, WorkflowRef, SingletonConfig, ConcurrencyConfig, SearchAttributesSchema, StateStore, Transport, NamedTransport, ControlPlane, ScheduledWorkflow, RetentionPolicy, QueueConfig, AdmissionBackend, WorkflowInputOf, StartOptions, RunResult, RunGateway, WorkflowEngine, EntityHandler, DurableTopology, RunDetailOptions, RunDetail, FanPageQuery, FanPage, RunQuery, RunListItem, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, GroupHealth, RunWaiting, EngineEvent, RunRequest, RunReply, StepInvocation, WorkflowRun, TenantEvent } from '@dudousxd/nestjs-durable-core';
|
|
2
|
-
export { AttributeFilter, DynamicWorkflowCtx, EngineEvent, InferSearchAttributes, RunDetail, RunGateway, RunListItem, RunQuery, RunStatus, RunWaiting, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, readSearchAttributes } from '@dudousxd/nestjs-durable-core';
|
|
1
|
+
import { WorkflowCtx, SearchAttributes, WorkflowClass, StepError, OnErrorInput, WorkflowRef, SingletonConfig, ConcurrencyConfig, SearchAttributesSchema, StateStore, Transport, NamedTransport, ControlPlane, ScheduledWorkflow, RetentionPolicy, QueueConfig, AdmissionBackend, WorkflowInputOf, StartOptions, RunResult, RunGateway, WorkflowEngine, EntityHandler, DurableTopology, RunDetailOptions, RunDetail, FanPageQuery, FanPage, RunQuery, RunListItem, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, GroupHealth, RunWaiting, EngineEvent, RunRequest, RunReply, StepInvocation, WorkflowRun, TenantEvent } from '@dudousxd/nestjs-durable-core';
|
|
2
|
+
export { AttributeFilter, DynamicWorkflowCtx, EngineEvent, InferSearchAttributes, OnErrorInput, RunDetail, RunGateway, RunListItem, RunQuery, RunStatus, RunWaiting, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, readSearchAttributes } from '@dudousxd/nestjs-durable-core';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { ConcurrencyOption, StartRunDeps, RunRedisWorkerOptions, RunningWorker, DurableWorkerRuntime } from '@dudousxd/durable-worker';
|
|
5
5
|
import { DynamicModule, InjectionToken, OnModuleInit, OnApplicationBootstrap, OnApplicationShutdown, Provider } from '@nestjs/common';
|
|
@@ -108,6 +108,11 @@ interface WorkflowMeta {
|
|
|
108
108
|
version: string;
|
|
109
109
|
/** The workflow this workflow's dead runs route to (a name or a class). See `WorkflowOptions`. */
|
|
110
110
|
deadLetterWorkflow?: WorkflowRef | undefined;
|
|
111
|
+
/** Where failed runs are routed by error code. See `WorkflowOptions`. */
|
|
112
|
+
onError?: {
|
|
113
|
+
code?: string | ErrorClassWithCode;
|
|
114
|
+
workflow: WorkflowRef;
|
|
115
|
+
}[] | undefined;
|
|
111
116
|
/** Static searchable labels stamped on every run of this workflow. See `WorkflowOptions`. */
|
|
112
117
|
tags?: string[] | undefined;
|
|
113
118
|
/** Per-key serialization (a durable mutex). See `WorkflowOptions`. */
|
|
@@ -146,6 +151,16 @@ interface WorkflowOptions {
|
|
|
146
151
|
* {@link DeadLetter} payload, idempotent by a `dlq:<runId>` id.
|
|
147
152
|
*/
|
|
148
153
|
deadLetterWorkflow?: WorkflowRef;
|
|
154
|
+
/**
|
|
155
|
+
* Route failed runs of this workflow to other **registered** workflows by error code — the
|
|
156
|
+
* separate-class form of an `@OnError` method (see it for the semantics). Each handler receives an
|
|
157
|
+
* {@link OnErrorInput}; omit `code` for the catch-all. A code routed here and by an `@OnError`
|
|
158
|
+
* method on the class is a boot-time error.
|
|
159
|
+
*/
|
|
160
|
+
onError?: {
|
|
161
|
+
code?: string | ErrorClassWithCode;
|
|
162
|
+
workflow: WorkflowRef;
|
|
163
|
+
}[];
|
|
149
164
|
/**
|
|
150
165
|
* Static labels stamped on **every run** of this workflow (e.g. `tags: ['etl', 'critical']`) and
|
|
151
166
|
* merged with any per-run tags passed to `start`. Searchable/filterable in the dashboard.
|
|
@@ -356,6 +371,42 @@ interface DeadLetter<TInput = unknown> {
|
|
|
356
371
|
*/
|
|
357
372
|
declare function DeadLetter(): MethodDecorator;
|
|
358
373
|
declare function isDeadLetterHandler(method: Function): boolean;
|
|
374
|
+
declare const ON_ERROR_METADATA: unique symbol;
|
|
375
|
+
/**
|
|
376
|
+
* An error class that declares the `code` it is thrown with (`static readonly code = 'invalid_line'`).
|
|
377
|
+
* `@OnError(Class)` matches on that code, not on `instanceof`: a dispatched step's error reaches the
|
|
378
|
+
* workflow as a plain `{ message, code }`, without its class.
|
|
379
|
+
*/
|
|
380
|
+
interface ErrorClassWithCode {
|
|
381
|
+
readonly code: string;
|
|
382
|
+
}
|
|
383
|
+
type WorkflowShape = {
|
|
384
|
+
run(ctx: any, input: any): Promise<unknown>;
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* An `@OnError` method: a workflow body that receives the failed run's {@link OnErrorInput}, typed with
|
|
388
|
+
* `run`'s input, and returns what `run` returns.
|
|
389
|
+
*/
|
|
390
|
+
type OnErrorMethod<T extends WorkflowShape> = (ctx: WorkflowCtx<any>, failure: OnErrorInput<Parameters<T['run']>[1]>) => Promise<Awaited<ReturnType<T['run']>>>;
|
|
391
|
+
/**
|
|
392
|
+
* Marks a method on a `@Workflow` class as the handler for a failure of that workflow's runs. When a
|
|
393
|
+
* run ends `failed` with an error of the given `code` (a string, or an {@link ErrorClassWithCode}),
|
|
394
|
+
* the engine starts the method as its own durable workflow — registered as
|
|
395
|
+
* `<workflow>.onError.<method>`, with a `<runId>.onError` id — and the failed run waits for it, then
|
|
396
|
+
* settles with its outcome: the method's return value as its output, or its error. Without an
|
|
397
|
+
* argument it takes any failure no other code matches.
|
|
398
|
+
*
|
|
399
|
+
* The engine routes the failure, so this holds for whatever ran the body (inline, an in-app worker,
|
|
400
|
+
* another runtime). The method's signature is checked against the workflow: `(ctx, failure)`, with
|
|
401
|
+
* `failure.input` typed as `run`'s input and the return type as `run`'s. Stack the decorator to give
|
|
402
|
+
* one method several codes. Saga compensations of the failed body run before the handoff;
|
|
403
|
+
* cancellation and non-determinism are never routed.
|
|
404
|
+
*/
|
|
405
|
+
declare function OnError(match?: string | ErrorClassWithCode): <T extends WorkflowShape>(_target: T, _propertyKey: string | symbol, descriptor: {
|
|
406
|
+
value?: OnErrorMethod<T> | undefined;
|
|
407
|
+
}) => void;
|
|
408
|
+
/** The codes an `@OnError` method takes (`undefined` for the catch-all), or undefined if it has none. */
|
|
409
|
+
declare function onErrorCodesOf(method: Function): (string | undefined)[] | undefined;
|
|
359
410
|
declare const ON_EVENT_METADATA: unique symbol;
|
|
360
411
|
/**
|
|
361
412
|
* Subscribe a `@Workflow` class to one or more events: when any of them is published via
|
|
@@ -500,6 +551,37 @@ interface DurableModuleOptions {
|
|
|
500
551
|
* Ignored when `remoteRedispatchMs` is unset. Operator only.
|
|
501
552
|
*/
|
|
502
553
|
remoteRedispatchMax?: number;
|
|
554
|
+
/**
|
|
555
|
+
* Fallback wake-up (ms) for a run suspended on an event (child, signal, `waitForEvent`, remote
|
|
556
|
+
* result) whose wake-up was lost: the reconcile pass re-drives it after this window, an idempotent
|
|
557
|
+
* replay that re-suspends a still-pending wait. Defaults to 300000 (5min); `0` disables it.
|
|
558
|
+
* See `WorkflowEngineDeps.reconcileMs`. Operator only.
|
|
559
|
+
*/
|
|
560
|
+
reconcileMs?: number;
|
|
561
|
+
/**
|
|
562
|
+
* The most due timers one timer-poll pass loads and drives, most overdue first, so a wave of
|
|
563
|
+
* thousands of due runs is worked through in batches. Defaults to 500; a non-finite or sub-1 value
|
|
564
|
+
* falls back to the default. See `WorkflowEngineDeps.timerBatchSize`. Operator only.
|
|
565
|
+
*/
|
|
566
|
+
timerBatchSize?: number;
|
|
567
|
+
/**
|
|
568
|
+
* Retention (ms) for a buffered event that no `waitForEvent` ever claims; the reconcile pass prunes
|
|
569
|
+
* rows past `publishedAt + eventBufferTtlMs`. Omit (or `0`) to keep them until consumed, the
|
|
570
|
+
* default. See `WorkflowEngineDeps.eventBufferTtlMs`. Operator only.
|
|
571
|
+
*/
|
|
572
|
+
eventBufferTtlMs?: number;
|
|
573
|
+
/**
|
|
574
|
+
* How long (ms) a run parked `blocked` (no capable, protocol-compatible live worker) waits before
|
|
575
|
+
* the blocked-recovery poll re-checks the fleet. Defaults to 5000. See
|
|
576
|
+
* `WorkflowEngineDeps.blockedPollMs`. Operator only.
|
|
577
|
+
*/
|
|
578
|
+
blockedPollMs?: number;
|
|
579
|
+
/**
|
|
580
|
+
* Persist a `running` checkpoint when a local step's body begins, so an in-flight step survives a
|
|
581
|
+
* dashboard reload. Defaults to `true`; set `false` on hot paths with many short local steps to
|
|
582
|
+
* halve their checkpoint writes. See `WorkflowEngineDeps.trackStepStart`. Operator only.
|
|
583
|
+
*/
|
|
584
|
+
trackStepStart?: boolean;
|
|
503
585
|
/**
|
|
504
586
|
* The **default** workflow to route dead-lettered runs to, for workflows that don't declare their
|
|
505
587
|
* own. When a run is moved to `dead` (exceeded `maxRecoveryAttempts`), the started handler gets a
|
|
@@ -773,9 +855,10 @@ type RunRedisWorkerFn = (opts: RunRedisWorkerOptions) => Promise<RunningWorker>;
|
|
|
773
855
|
*/
|
|
774
856
|
declare class ThinWorkflowRegistrar implements OnModuleInit {
|
|
775
857
|
private readonly discovery;
|
|
858
|
+
private readonly metadataScanner;
|
|
776
859
|
private readonly runtime;
|
|
777
860
|
private readonly options;
|
|
778
|
-
constructor(discovery: DiscoveryService, runtime: DurableWorkerRuntime | null, options: DurableModuleOptions);
|
|
861
|
+
constructor(discovery: DiscoveryService, metadataScanner: MetadataScanner, runtime: DurableWorkerRuntime | null, options: DurableModuleOptions);
|
|
779
862
|
onModuleInit(): void;
|
|
780
863
|
}
|
|
781
864
|
/**
|
|
@@ -940,13 +1023,25 @@ declare class ProxyRunGateway implements RunGateway {
|
|
|
940
1023
|
private readonly transport;
|
|
941
1024
|
private readonly tenant;
|
|
942
1025
|
private readonly timeoutMs;
|
|
1026
|
+
private readonly capabilityTtlMs;
|
|
943
1027
|
private readonly pending;
|
|
944
|
-
|
|
1028
|
+
/** Verb → when to ask the control plane for it again, after it answered that it does not know it.
|
|
1029
|
+
* During a rolling upgrade the control plane is several pods of mixed versions behind one queue,
|
|
1030
|
+
* and a reply does not say which pod sent it, so the whole control plane is assumed old until the
|
|
1031
|
+
* entry expires. */
|
|
1032
|
+
private readonly unsupportedUntil;
|
|
1033
|
+
constructor(transport: Transport, tenant: string, timeoutMs?: number, capabilityTtlMs?: number);
|
|
945
1034
|
private handleReply;
|
|
946
1035
|
private request;
|
|
947
1036
|
topology(): DurableTopology;
|
|
1037
|
+
/**
|
|
1038
|
+
* A control plane that predates {@link RunDetailOptions} ignores them and sends the full detail;
|
|
1039
|
+
* a summarized detail always carries `fans`, so its absence means the summary is made here.
|
|
1040
|
+
*/
|
|
948
1041
|
getRunDetail(runId: string, options?: RunDetailOptions): Promise<RunDetail | null>;
|
|
1042
|
+
/** Paged from the full detail when the control plane is too old to page a fan itself. */
|
|
949
1043
|
getFanMembers(runId: string, group: string, query: FanPageQuery): Promise<FanPage | null>;
|
|
1044
|
+
private knownUnsupported;
|
|
950
1045
|
/** The control plane's `StoreRunGateway` resolves each run's `waiting` descriptor; the reply carries
|
|
951
1046
|
* it through as plain JSON, so a tenant's list rows name the wait too. */
|
|
952
1047
|
listRuns(query: RunQuery): Promise<RunListItem[]>;
|
|
@@ -989,6 +1084,12 @@ declare function isOperatorRole(options: DurableModuleOptions): boolean;
|
|
|
989
1084
|
*/
|
|
990
1085
|
declare function isDrivingOperator(options: DurableModuleOptions): boolean;
|
|
991
1086
|
|
|
1087
|
+
/**
|
|
1088
|
+
* The error `code` a responder replies with for a verb it does not know, so a newer tenant can tell
|
|
1089
|
+
* "this control plane is older than me" from a real failure and fall back at once. Earlier
|
|
1090
|
+
* responders reply `ok: true` with no `data` instead; `ProxyRunGateway` reads both.
|
|
1091
|
+
*/
|
|
1092
|
+
declare const UNSUPPORTED_RUN_REQUEST = "unsupported-request";
|
|
992
1093
|
/** The narrow slice of `Transport` the responder needs — a tenant's read/control request in, a
|
|
993
1094
|
* correlated reply out. Both are OPTIONAL on the full `Transport` interface (only broker
|
|
994
1095
|
* transports carry the run-request/reply protocol); the caller capability-checks before wiring
|
|
@@ -1204,4 +1305,4 @@ declare class WorkflowService {
|
|
|
1204
1305
|
}): Promise<number>;
|
|
1205
1306
|
}
|
|
1206
1307
|
|
|
1207
|
-
export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, DEAD_LETTER_METADATA, DURABLE_STEP_METADATA, DURABLE_WORKER_RUNNERS, DURABLE_WORKER_RUNTIME, DeadLetter, DurableModule, type DurableModuleAsyncOptions, type DurableModuleOptions, type DurableRetentionOptions, DurableStartClient, DurableStep, type DurableStepInterceptor, type DurableStepMeta, ENTITY_METADATA, ENTITY_ON_METADATA, Entity, EntityService, IN_APP_RUN_REDIS_WORKER, IN_APP_WORKER_BINDING, IN_APP_WORKER_RUNNERS, IN_APP_WORKER_RUNTIME, type InAppWorkerBinding, InAppWorkerBootstrap, ON_EVENT_METADATA, On, OnDurableEvent, OnEvent, ProxyRunGateway, RUN_GATEWAY, RUN_REDIS_WORKER, type RunLookupStore, type RunRedisWorkerFn, RunRequestResponder, type RunRequestTransport, STEP_INTERCEPTOR_METADATA, Step, StepInterceptor, type StepOptions, StoreRunGateway, TenantEventRepublisher, ThinStepRegistrar, ThinWorkerBootstrap, ThinWorkflowRegistrar, type UserRef, WORKFLOW_METADATA, Workflow, type WorkflowAttributesOf, type WorkflowMeta, type WorkflowOptions, WorkflowService, attributesOf, entityConfigFor, getDurableStepMeta, getEntityMeta, getOnEvents, getWorkflowMeta, inAppWorkerProviders, isDeadLetterHandler, isDrivingOperator, isOperatorRole, isStepInterceptor, thinWorkerProviders, unavailableRunGateway };
|
|
1308
|
+
export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, DEAD_LETTER_METADATA, DURABLE_STEP_METADATA, DURABLE_WORKER_RUNNERS, DURABLE_WORKER_RUNTIME, DeadLetter, DurableModule, type DurableModuleAsyncOptions, type DurableModuleOptions, type DurableRetentionOptions, DurableStartClient, DurableStep, type DurableStepInterceptor, type DurableStepMeta, ENTITY_METADATA, ENTITY_ON_METADATA, Entity, EntityService, type ErrorClassWithCode, IN_APP_RUN_REDIS_WORKER, IN_APP_WORKER_BINDING, IN_APP_WORKER_RUNNERS, IN_APP_WORKER_RUNTIME, type InAppWorkerBinding, InAppWorkerBootstrap, ON_ERROR_METADATA, ON_EVENT_METADATA, On, OnDurableEvent, OnError, type OnErrorMethod, OnEvent, ProxyRunGateway, RUN_GATEWAY, RUN_REDIS_WORKER, type RunLookupStore, type RunRedisWorkerFn, RunRequestResponder, type RunRequestTransport, STEP_INTERCEPTOR_METADATA, Step, StepInterceptor, type StepOptions, StoreRunGateway, TenantEventRepublisher, ThinStepRegistrar, ThinWorkerBootstrap, ThinWorkflowRegistrar, UNSUPPORTED_RUN_REQUEST, type UserRef, WORKFLOW_METADATA, Workflow, type WorkflowAttributesOf, type WorkflowMeta, type WorkflowOptions, WorkflowService, attributesOf, entityConfigFor, getDurableStepMeta, getEntityMeta, getOnEvents, getWorkflowMeta, inAppWorkerProviders, isDeadLetterHandler, isDrivingOperator, isOperatorRole, isStepInterceptor, onErrorCodesOf, thinWorkerProviders, unavailableRunGateway };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { WorkflowCtx, SearchAttributes, WorkflowClass, StepError, WorkflowRef, SingletonConfig, ConcurrencyConfig, SearchAttributesSchema, StateStore, Transport, NamedTransport, ControlPlane, ScheduledWorkflow, RetentionPolicy, QueueConfig, AdmissionBackend, WorkflowInputOf, StartOptions, RunResult, RunGateway, WorkflowEngine, EntityHandler, DurableTopology, RunDetailOptions, RunDetail, FanPageQuery, FanPage, RunQuery, RunListItem, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, GroupHealth, RunWaiting, EngineEvent, RunRequest, RunReply, StepInvocation, WorkflowRun, TenantEvent } from '@dudousxd/nestjs-durable-core';
|
|
2
|
-
export { AttributeFilter, DynamicWorkflowCtx, EngineEvent, InferSearchAttributes, RunDetail, RunGateway, RunListItem, RunQuery, RunStatus, RunWaiting, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, readSearchAttributes } from '@dudousxd/nestjs-durable-core';
|
|
1
|
+
import { WorkflowCtx, SearchAttributes, WorkflowClass, StepError, OnErrorInput, WorkflowRef, SingletonConfig, ConcurrencyConfig, SearchAttributesSchema, StateStore, Transport, NamedTransport, ControlPlane, ScheduledWorkflow, RetentionPolicy, QueueConfig, AdmissionBackend, WorkflowInputOf, StartOptions, RunResult, RunGateway, WorkflowEngine, EntityHandler, DurableTopology, RunDetailOptions, RunDetail, FanPageQuery, FanPage, RunQuery, RunListItem, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, GroupHealth, RunWaiting, EngineEvent, RunRequest, RunReply, StepInvocation, WorkflowRun, TenantEvent } from '@dudousxd/nestjs-durable-core';
|
|
2
|
+
export { AttributeFilter, DynamicWorkflowCtx, EngineEvent, InferSearchAttributes, OnErrorInput, RunDetail, RunGateway, RunListItem, RunQuery, RunStatus, RunWaiting, SearchAttributes, SearchAttributesSchema, StepCheckpoint, StepEvent, StepLogger, WorkflowCtx, WorkflowEngine, WorkflowHandler, WorkflowRun, readSearchAttributes } from '@dudousxd/nestjs-durable-core';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { ConcurrencyOption, StartRunDeps, RunRedisWorkerOptions, RunningWorker, DurableWorkerRuntime } from '@dudousxd/durable-worker';
|
|
5
5
|
import { DynamicModule, InjectionToken, OnModuleInit, OnApplicationBootstrap, OnApplicationShutdown, Provider } from '@nestjs/common';
|
|
@@ -108,6 +108,11 @@ interface WorkflowMeta {
|
|
|
108
108
|
version: string;
|
|
109
109
|
/** The workflow this workflow's dead runs route to (a name or a class). See `WorkflowOptions`. */
|
|
110
110
|
deadLetterWorkflow?: WorkflowRef | undefined;
|
|
111
|
+
/** Where failed runs are routed by error code. See `WorkflowOptions`. */
|
|
112
|
+
onError?: {
|
|
113
|
+
code?: string | ErrorClassWithCode;
|
|
114
|
+
workflow: WorkflowRef;
|
|
115
|
+
}[] | undefined;
|
|
111
116
|
/** Static searchable labels stamped on every run of this workflow. See `WorkflowOptions`. */
|
|
112
117
|
tags?: string[] | undefined;
|
|
113
118
|
/** Per-key serialization (a durable mutex). See `WorkflowOptions`. */
|
|
@@ -146,6 +151,16 @@ interface WorkflowOptions {
|
|
|
146
151
|
* {@link DeadLetter} payload, idempotent by a `dlq:<runId>` id.
|
|
147
152
|
*/
|
|
148
153
|
deadLetterWorkflow?: WorkflowRef;
|
|
154
|
+
/**
|
|
155
|
+
* Route failed runs of this workflow to other **registered** workflows by error code — the
|
|
156
|
+
* separate-class form of an `@OnError` method (see it for the semantics). Each handler receives an
|
|
157
|
+
* {@link OnErrorInput}; omit `code` for the catch-all. A code routed here and by an `@OnError`
|
|
158
|
+
* method on the class is a boot-time error.
|
|
159
|
+
*/
|
|
160
|
+
onError?: {
|
|
161
|
+
code?: string | ErrorClassWithCode;
|
|
162
|
+
workflow: WorkflowRef;
|
|
163
|
+
}[];
|
|
149
164
|
/**
|
|
150
165
|
* Static labels stamped on **every run** of this workflow (e.g. `tags: ['etl', 'critical']`) and
|
|
151
166
|
* merged with any per-run tags passed to `start`. Searchable/filterable in the dashboard.
|
|
@@ -356,6 +371,42 @@ interface DeadLetter<TInput = unknown> {
|
|
|
356
371
|
*/
|
|
357
372
|
declare function DeadLetter(): MethodDecorator;
|
|
358
373
|
declare function isDeadLetterHandler(method: Function): boolean;
|
|
374
|
+
declare const ON_ERROR_METADATA: unique symbol;
|
|
375
|
+
/**
|
|
376
|
+
* An error class that declares the `code` it is thrown with (`static readonly code = 'invalid_line'`).
|
|
377
|
+
* `@OnError(Class)` matches on that code, not on `instanceof`: a dispatched step's error reaches the
|
|
378
|
+
* workflow as a plain `{ message, code }`, without its class.
|
|
379
|
+
*/
|
|
380
|
+
interface ErrorClassWithCode {
|
|
381
|
+
readonly code: string;
|
|
382
|
+
}
|
|
383
|
+
type WorkflowShape = {
|
|
384
|
+
run(ctx: any, input: any): Promise<unknown>;
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* An `@OnError` method: a workflow body that receives the failed run's {@link OnErrorInput}, typed with
|
|
388
|
+
* `run`'s input, and returns what `run` returns.
|
|
389
|
+
*/
|
|
390
|
+
type OnErrorMethod<T extends WorkflowShape> = (ctx: WorkflowCtx<any>, failure: OnErrorInput<Parameters<T['run']>[1]>) => Promise<Awaited<ReturnType<T['run']>>>;
|
|
391
|
+
/**
|
|
392
|
+
* Marks a method on a `@Workflow` class as the handler for a failure of that workflow's runs. When a
|
|
393
|
+
* run ends `failed` with an error of the given `code` (a string, or an {@link ErrorClassWithCode}),
|
|
394
|
+
* the engine starts the method as its own durable workflow — registered as
|
|
395
|
+
* `<workflow>.onError.<method>`, with a `<runId>.onError` id — and the failed run waits for it, then
|
|
396
|
+
* settles with its outcome: the method's return value as its output, or its error. Without an
|
|
397
|
+
* argument it takes any failure no other code matches.
|
|
398
|
+
*
|
|
399
|
+
* The engine routes the failure, so this holds for whatever ran the body (inline, an in-app worker,
|
|
400
|
+
* another runtime). The method's signature is checked against the workflow: `(ctx, failure)`, with
|
|
401
|
+
* `failure.input` typed as `run`'s input and the return type as `run`'s. Stack the decorator to give
|
|
402
|
+
* one method several codes. Saga compensations of the failed body run before the handoff;
|
|
403
|
+
* cancellation and non-determinism are never routed.
|
|
404
|
+
*/
|
|
405
|
+
declare function OnError(match?: string | ErrorClassWithCode): <T extends WorkflowShape>(_target: T, _propertyKey: string | symbol, descriptor: {
|
|
406
|
+
value?: OnErrorMethod<T> | undefined;
|
|
407
|
+
}) => void;
|
|
408
|
+
/** The codes an `@OnError` method takes (`undefined` for the catch-all), or undefined if it has none. */
|
|
409
|
+
declare function onErrorCodesOf(method: Function): (string | undefined)[] | undefined;
|
|
359
410
|
declare const ON_EVENT_METADATA: unique symbol;
|
|
360
411
|
/**
|
|
361
412
|
* Subscribe a `@Workflow` class to one or more events: when any of them is published via
|
|
@@ -500,6 +551,37 @@ interface DurableModuleOptions {
|
|
|
500
551
|
* Ignored when `remoteRedispatchMs` is unset. Operator only.
|
|
501
552
|
*/
|
|
502
553
|
remoteRedispatchMax?: number;
|
|
554
|
+
/**
|
|
555
|
+
* Fallback wake-up (ms) for a run suspended on an event (child, signal, `waitForEvent`, remote
|
|
556
|
+
* result) whose wake-up was lost: the reconcile pass re-drives it after this window, an idempotent
|
|
557
|
+
* replay that re-suspends a still-pending wait. Defaults to 300000 (5min); `0` disables it.
|
|
558
|
+
* See `WorkflowEngineDeps.reconcileMs`. Operator only.
|
|
559
|
+
*/
|
|
560
|
+
reconcileMs?: number;
|
|
561
|
+
/**
|
|
562
|
+
* The most due timers one timer-poll pass loads and drives, most overdue first, so a wave of
|
|
563
|
+
* thousands of due runs is worked through in batches. Defaults to 500; a non-finite or sub-1 value
|
|
564
|
+
* falls back to the default. See `WorkflowEngineDeps.timerBatchSize`. Operator only.
|
|
565
|
+
*/
|
|
566
|
+
timerBatchSize?: number;
|
|
567
|
+
/**
|
|
568
|
+
* Retention (ms) for a buffered event that no `waitForEvent` ever claims; the reconcile pass prunes
|
|
569
|
+
* rows past `publishedAt + eventBufferTtlMs`. Omit (or `0`) to keep them until consumed, the
|
|
570
|
+
* default. See `WorkflowEngineDeps.eventBufferTtlMs`. Operator only.
|
|
571
|
+
*/
|
|
572
|
+
eventBufferTtlMs?: number;
|
|
573
|
+
/**
|
|
574
|
+
* How long (ms) a run parked `blocked` (no capable, protocol-compatible live worker) waits before
|
|
575
|
+
* the blocked-recovery poll re-checks the fleet. Defaults to 5000. See
|
|
576
|
+
* `WorkflowEngineDeps.blockedPollMs`. Operator only.
|
|
577
|
+
*/
|
|
578
|
+
blockedPollMs?: number;
|
|
579
|
+
/**
|
|
580
|
+
* Persist a `running` checkpoint when a local step's body begins, so an in-flight step survives a
|
|
581
|
+
* dashboard reload. Defaults to `true`; set `false` on hot paths with many short local steps to
|
|
582
|
+
* halve their checkpoint writes. See `WorkflowEngineDeps.trackStepStart`. Operator only.
|
|
583
|
+
*/
|
|
584
|
+
trackStepStart?: boolean;
|
|
503
585
|
/**
|
|
504
586
|
* The **default** workflow to route dead-lettered runs to, for workflows that don't declare their
|
|
505
587
|
* own. When a run is moved to `dead` (exceeded `maxRecoveryAttempts`), the started handler gets a
|
|
@@ -773,9 +855,10 @@ type RunRedisWorkerFn = (opts: RunRedisWorkerOptions) => Promise<RunningWorker>;
|
|
|
773
855
|
*/
|
|
774
856
|
declare class ThinWorkflowRegistrar implements OnModuleInit {
|
|
775
857
|
private readonly discovery;
|
|
858
|
+
private readonly metadataScanner;
|
|
776
859
|
private readonly runtime;
|
|
777
860
|
private readonly options;
|
|
778
|
-
constructor(discovery: DiscoveryService, runtime: DurableWorkerRuntime | null, options: DurableModuleOptions);
|
|
861
|
+
constructor(discovery: DiscoveryService, metadataScanner: MetadataScanner, runtime: DurableWorkerRuntime | null, options: DurableModuleOptions);
|
|
779
862
|
onModuleInit(): void;
|
|
780
863
|
}
|
|
781
864
|
/**
|
|
@@ -940,13 +1023,25 @@ declare class ProxyRunGateway implements RunGateway {
|
|
|
940
1023
|
private readonly transport;
|
|
941
1024
|
private readonly tenant;
|
|
942
1025
|
private readonly timeoutMs;
|
|
1026
|
+
private readonly capabilityTtlMs;
|
|
943
1027
|
private readonly pending;
|
|
944
|
-
|
|
1028
|
+
/** Verb → when to ask the control plane for it again, after it answered that it does not know it.
|
|
1029
|
+
* During a rolling upgrade the control plane is several pods of mixed versions behind one queue,
|
|
1030
|
+
* and a reply does not say which pod sent it, so the whole control plane is assumed old until the
|
|
1031
|
+
* entry expires. */
|
|
1032
|
+
private readonly unsupportedUntil;
|
|
1033
|
+
constructor(transport: Transport, tenant: string, timeoutMs?: number, capabilityTtlMs?: number);
|
|
945
1034
|
private handleReply;
|
|
946
1035
|
private request;
|
|
947
1036
|
topology(): DurableTopology;
|
|
1037
|
+
/**
|
|
1038
|
+
* A control plane that predates {@link RunDetailOptions} ignores them and sends the full detail;
|
|
1039
|
+
* a summarized detail always carries `fans`, so its absence means the summary is made here.
|
|
1040
|
+
*/
|
|
948
1041
|
getRunDetail(runId: string, options?: RunDetailOptions): Promise<RunDetail | null>;
|
|
1042
|
+
/** Paged from the full detail when the control plane is too old to page a fan itself. */
|
|
949
1043
|
getFanMembers(runId: string, group: string, query: FanPageQuery): Promise<FanPage | null>;
|
|
1044
|
+
private knownUnsupported;
|
|
950
1045
|
/** The control plane's `StoreRunGateway` resolves each run's `waiting` descriptor; the reply carries
|
|
951
1046
|
* it through as plain JSON, so a tenant's list rows name the wait too. */
|
|
952
1047
|
listRuns(query: RunQuery): Promise<RunListItem[]>;
|
|
@@ -989,6 +1084,12 @@ declare function isOperatorRole(options: DurableModuleOptions): boolean;
|
|
|
989
1084
|
*/
|
|
990
1085
|
declare function isDrivingOperator(options: DurableModuleOptions): boolean;
|
|
991
1086
|
|
|
1087
|
+
/**
|
|
1088
|
+
* The error `code` a responder replies with for a verb it does not know, so a newer tenant can tell
|
|
1089
|
+
* "this control plane is older than me" from a real failure and fall back at once. Earlier
|
|
1090
|
+
* responders reply `ok: true` with no `data` instead; `ProxyRunGateway` reads both.
|
|
1091
|
+
*/
|
|
1092
|
+
declare const UNSUPPORTED_RUN_REQUEST = "unsupported-request";
|
|
992
1093
|
/** The narrow slice of `Transport` the responder needs — a tenant's read/control request in, a
|
|
993
1094
|
* correlated reply out. Both are OPTIONAL on the full `Transport` interface (only broker
|
|
994
1095
|
* transports carry the run-request/reply protocol); the caller capability-checks before wiring
|
|
@@ -1204,4 +1305,4 @@ declare class WorkflowService {
|
|
|
1204
1305
|
}): Promise<number>;
|
|
1205
1306
|
}
|
|
1206
1307
|
|
|
1207
|
-
export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, DEAD_LETTER_METADATA, DURABLE_STEP_METADATA, DURABLE_WORKER_RUNNERS, DURABLE_WORKER_RUNTIME, DeadLetter, DurableModule, type DurableModuleAsyncOptions, type DurableModuleOptions, type DurableRetentionOptions, DurableStartClient, DurableStep, type DurableStepInterceptor, type DurableStepMeta, ENTITY_METADATA, ENTITY_ON_METADATA, Entity, EntityService, IN_APP_RUN_REDIS_WORKER, IN_APP_WORKER_BINDING, IN_APP_WORKER_RUNNERS, IN_APP_WORKER_RUNTIME, type InAppWorkerBinding, InAppWorkerBootstrap, ON_EVENT_METADATA, On, OnDurableEvent, OnEvent, ProxyRunGateway, RUN_GATEWAY, RUN_REDIS_WORKER, type RunLookupStore, type RunRedisWorkerFn, RunRequestResponder, type RunRequestTransport, STEP_INTERCEPTOR_METADATA, Step, StepInterceptor, type StepOptions, StoreRunGateway, TenantEventRepublisher, ThinStepRegistrar, ThinWorkerBootstrap, ThinWorkflowRegistrar, type UserRef, WORKFLOW_METADATA, Workflow, type WorkflowAttributesOf, type WorkflowMeta, type WorkflowOptions, WorkflowService, attributesOf, entityConfigFor, getDurableStepMeta, getEntityMeta, getOnEvents, getWorkflowMeta, inAppWorkerProviders, isDeadLetterHandler, isDrivingOperator, isOperatorRole, isStepInterceptor, thinWorkerProviders, unavailableRunGateway };
|
|
1308
|
+
export { CONTEXT_ACCESSOR, type ContextAccessor, type ContextStore, DEAD_LETTER_METADATA, DURABLE_STEP_METADATA, DURABLE_WORKER_RUNNERS, DURABLE_WORKER_RUNTIME, DeadLetter, DurableModule, type DurableModuleAsyncOptions, type DurableModuleOptions, type DurableRetentionOptions, DurableStartClient, DurableStep, type DurableStepInterceptor, type DurableStepMeta, ENTITY_METADATA, ENTITY_ON_METADATA, Entity, EntityService, type ErrorClassWithCode, IN_APP_RUN_REDIS_WORKER, IN_APP_WORKER_BINDING, IN_APP_WORKER_RUNNERS, IN_APP_WORKER_RUNTIME, type InAppWorkerBinding, InAppWorkerBootstrap, ON_ERROR_METADATA, ON_EVENT_METADATA, On, OnDurableEvent, OnError, type OnErrorMethod, OnEvent, ProxyRunGateway, RUN_GATEWAY, RUN_REDIS_WORKER, type RunLookupStore, type RunRedisWorkerFn, RunRequestResponder, type RunRequestTransport, STEP_INTERCEPTOR_METADATA, Step, StepInterceptor, type StepOptions, StoreRunGateway, TenantEventRepublisher, ThinStepRegistrar, ThinWorkerBootstrap, ThinWorkflowRegistrar, UNSUPPORTED_RUN_REQUEST, type UserRef, WORKFLOW_METADATA, Workflow, type WorkflowAttributesOf, type WorkflowMeta, type WorkflowOptions, WorkflowService, attributesOf, entityConfigFor, getDurableStepMeta, getEntityMeta, getOnEvents, getWorkflowMeta, inAppWorkerProviders, isDeadLetterHandler, isDrivingOperator, isOperatorRole, isStepInterceptor, onErrorCodesOf, thinWorkerProviders, unavailableRunGateway };
|