@dudousxd/nestjs-durable-core 0.50.1 → 0.52.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 +15 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -1
- package/dist/index.d.ts +112 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1749,6 +1749,59 @@ declare function runInWorkflowCtx<T>(ctx: WorkflowCtx, fn: () => T): T;
|
|
|
1749
1749
|
*/
|
|
1750
1750
|
declare function currentWorkflowCtx(): WorkflowCtx | undefined;
|
|
1751
1751
|
|
|
1752
|
+
/**
|
|
1753
|
+
* Cross-package, cross-runtime marker for engine CONTROL-FLOW signals — {@link WorkflowSuspended}
|
|
1754
|
+
* and {@link ContinueAsNew} (this package), plus the thin worker's {@link
|
|
1755
|
+
* import('@dudousxd/durable-worker').Suspend} (`@dudousxd/durable-worker`, the BullMQ
|
|
1756
|
+
* route-by-handler runtime). These are thrown by `WorkflowCtx`/`WorkflowContext` ops to unwind the
|
|
1757
|
+
* current turn — never real failures — so a workflow's `catch` block MUST rethrow them untouched.
|
|
1758
|
+
* Running a failure/cleanup path on a control-flow signal corrupts the run: it emits extra
|
|
1759
|
+
* `recordStep` commands into history that a subsequent replay didn't produce the first time,
|
|
1760
|
+
* surfacing as a `NonDeterminismError`/`NondeterminismError` on resume.
|
|
1761
|
+
*
|
|
1762
|
+
* `Symbol.for` (the GLOBAL registry), NOT a plain `Symbol()` — so a duplicate copy of this module
|
|
1763
|
+
* (pnpm peer-dependency multiplexing, a dual ESM/CJS load, or the SEPARATE `@dudousxd/durable-worker`
|
|
1764
|
+
* package declaring the same `Symbol.for` key locally) still collapses onto the SAME symbol. Same
|
|
1765
|
+
* rationale as `DURABLE_STEP_NAME` in `./step-name-symbol.ts`.
|
|
1766
|
+
*
|
|
1767
|
+
* Deliberately checked as a stamped property, NOT `instanceof` — `instanceof` only recognizes a
|
|
1768
|
+
* signal thrown by the SAME class the checking code imported, which fails across the in-process
|
|
1769
|
+
* engine (`@dudousxd/nestjs-durable-core`'s `WorkflowSuspended`/`ContinueAsNew`) and the thin worker
|
|
1770
|
+
* (`@dudousxd/durable-worker`'s `Suspend`) — two different classes for what is, from a workflow
|
|
1771
|
+
* author's catch block, the same "this isn't a real error, let it through" event.
|
|
1772
|
+
*
|
|
1773
|
+
* NOT designed to survive a serialization boundary (e.g. JSON over the wire) — these signals are
|
|
1774
|
+
* always thrown and caught in-process within a single replay turn, never (de)serialized, so a
|
|
1775
|
+
* stamped-but-not-cloneable property is sufficient.
|
|
1776
|
+
*/
|
|
1777
|
+
declare const CONTROL_FLOW_SIGNAL: unique symbol;
|
|
1778
|
+
/**
|
|
1779
|
+
* True for any engine control-flow signal (currently: {@link WorkflowSuspended}, {@link
|
|
1780
|
+
* ContinueAsNew}, and the thin worker's `Suspend`) — regardless of which runtime or module instance
|
|
1781
|
+
* threw it. Workflow `catch` blocks MUST rethrow these untouched; running a failure/cleanup path on
|
|
1782
|
+
* one corrupts the run's history (extra commands recorded during what replay will later see as a
|
|
1783
|
+
* suspend, not a failure) and the resumed replay dies with a non-determinism error.
|
|
1784
|
+
*
|
|
1785
|
+
* Deliberately NOT control-flow (do not add to this predicate):
|
|
1786
|
+
* - `Cancelled` (worker) / a cancelled run — a TERMINAL outcome the consumer may legitimately want
|
|
1787
|
+
* to observe and react to (e.g. release a lock), not a mid-turn unwind to rethrow untouched.
|
|
1788
|
+
* - `StepFailed` (worker) / an awaited step rejection reaching the engine — a REAL failure a
|
|
1789
|
+
* workflow's `catch` is meant to compensate for; misclassifying it as control-flow would swallow
|
|
1790
|
+
* genuine errors instead of protecting them.
|
|
1791
|
+
*
|
|
1792
|
+
* @example
|
|
1793
|
+
* ```ts
|
|
1794
|
+
* try {
|
|
1795
|
+
* await ctx.step('chargeCard', input);
|
|
1796
|
+
* } catch (error) {
|
|
1797
|
+
* if (isWorkflowControlFlowSignal(error)) throw error; // suspend/continue-as-new: rethrow as-is
|
|
1798
|
+
* await ctx.step('refund', input); // a REAL failure — safe to run cleanup here
|
|
1799
|
+
* throw error;
|
|
1800
|
+
* }
|
|
1801
|
+
* ```
|
|
1802
|
+
*/
|
|
1803
|
+
declare function isWorkflowControlFlowSignal(error: unknown): boolean;
|
|
1804
|
+
|
|
1752
1805
|
/**
|
|
1753
1806
|
* Back-compat alias of {@link WorkflowCtx}. `localStep` — the checkpointed in-process step primitive
|
|
1754
1807
|
* used for saga compensation — is now part of the public {@link WorkflowCtx}, so this type adds
|
|
@@ -2875,6 +2928,8 @@ declare class GatherError extends Error {
|
|
|
2875
2928
|
declare class WorkflowSuspended extends Error {
|
|
2876
2929
|
/** Epoch ms to auto-resume (durable sleep), or undefined when waiting on an external signal. */
|
|
2877
2930
|
readonly wakeAt?: number | undefined;
|
|
2931
|
+
/** Marks this as a control-flow signal — see {@link isWorkflowControlFlowSignal}. */
|
|
2932
|
+
readonly [CONTROL_FLOW_SIGNAL] = true;
|
|
2878
2933
|
constructor(wakeAt?: number);
|
|
2879
2934
|
}
|
|
2880
2935
|
/**
|
|
@@ -2884,6 +2939,8 @@ declare class WorkflowSuspended extends Error {
|
|
|
2884
2939
|
*/
|
|
2885
2940
|
declare class ContinueAsNew extends Error {
|
|
2886
2941
|
readonly input: unknown;
|
|
2942
|
+
/** Marks this as a control-flow signal — see {@link isWorkflowControlFlowSignal}. */
|
|
2943
|
+
readonly [CONTROL_FLOW_SIGNAL] = true;
|
|
2887
2944
|
constructor(input: unknown);
|
|
2888
2945
|
}
|
|
2889
2946
|
|
|
@@ -3369,6 +3426,60 @@ declare const STATE_STORE_CANONICAL: unique symbol;
|
|
|
3369
3426
|
declare const TRANSPORT_CANONICAL: unique symbol;
|
|
3370
3427
|
declare const DURABLE_OPTIONS_CANONICAL: unique symbol;
|
|
3371
3428
|
|
|
3429
|
+
/**
|
|
3430
|
+
* The OPT-IN declaration-site contract for a `@Workflow` class: `implements WorkflowHandler<TInput,
|
|
3431
|
+
* TOutput, A>` pins the class's `run(ctx, input)` signature against `TInput`/`TOutput`/`A` so a wrong
|
|
3432
|
+
* signature — a renamed method, swapped/missing param, wrong return type — is a compile error AT THE
|
|
3433
|
+
* CLASS instead of surfacing later as a runtime discovery failure (the `@Workflow` decorator finds no
|
|
3434
|
+
* `run` it recognizes) or a silently-wrong type flowing out of `ctx.child(ThisWorkflow, …)` /
|
|
3435
|
+
* `engine.start(ThisWorkflow, …)`. `A` also declares the run's {@link SearchAttributes} shape, so
|
|
3436
|
+
* `ctx.upsertSearchAttributes` is narrowed to it inside the workflow body — see
|
|
3437
|
+
* {@link SearchAttributesSchema} / {@link InferSearchAttributes} for pairing it with a `@Workflow({
|
|
3438
|
+
* searchAttributes })` schema.
|
|
3439
|
+
*
|
|
3440
|
+
* This is a TYPES-ONLY contract: nothing reads `implements WorkflowHandler` at runtime, registration
|
|
3441
|
+
* still goes through the `@Workflow` decorator + reflected metadata exactly as before, and a class
|
|
3442
|
+
* that doesn't implement it works exactly as it always has.
|
|
3443
|
+
*
|
|
3444
|
+
* IMPORTANT caveat: TypeScript does **not** contextually infer a method's parameter types from an
|
|
3445
|
+
* `implements` clause the way it does for e.g. an object literal assigned to a typed variable. The
|
|
3446
|
+
* class still has to annotate `ctx`/`input` itself — `implements` only CHECKS that what you wrote is
|
|
3447
|
+
* assignable to the interface; it doesn't write the annotations for you. Leaving `run`'s params
|
|
3448
|
+
* unannotated still leaves them `any`/inferred-from-usage, `implements` or not.
|
|
3449
|
+
*
|
|
3450
|
+
* @example
|
|
3451
|
+
* ```ts
|
|
3452
|
+
* import { z } from 'zod';
|
|
3453
|
+
* import { Workflow } from '@dudousxd/nestjs-durable';
|
|
3454
|
+
* import type { InferSearchAttributes, WorkflowCtx, WorkflowHandler } from '@dudousxd/nestjs-durable';
|
|
3455
|
+
*
|
|
3456
|
+
* const orderAttrs = z.object({
|
|
3457
|
+
* tier: z.enum(['free', 'pro']),
|
|
3458
|
+
* amount: z.number(),
|
|
3459
|
+
* });
|
|
3460
|
+
* type OrderAttrs = InferSearchAttributes<typeof orderAttrs>;
|
|
3461
|
+
*
|
|
3462
|
+
* interface CheckoutInput {
|
|
3463
|
+
* orderId: string;
|
|
3464
|
+
* }
|
|
3465
|
+
* interface CheckoutOutput {
|
|
3466
|
+
* receiptId: string;
|
|
3467
|
+
* }
|
|
3468
|
+
*
|
|
3469
|
+
* @Workflow({ name: 'checkout', searchAttributes: orderAttrs })
|
|
3470
|
+
* class CheckoutWorkflow implements WorkflowHandler<CheckoutInput, CheckoutOutput, OrderAttrs> {
|
|
3471
|
+
* async run(ctx: WorkflowCtx<OrderAttrs>, input: CheckoutInput): Promise<CheckoutOutput> {
|
|
3472
|
+
* await ctx.upsertSearchAttributes({ tier: 'pro', amount: 100 });
|
|
3473
|
+
* const receiptId = await ctx.step('charge-card', { orderId: input.orderId });
|
|
3474
|
+
* return { receiptId };
|
|
3475
|
+
* }
|
|
3476
|
+
* }
|
|
3477
|
+
* ```
|
|
3478
|
+
*/
|
|
3479
|
+
interface WorkflowHandler<TInput = unknown, TOutput = unknown, A extends SearchAttributes = SearchAttributes> {
|
|
3480
|
+
run(ctx: WorkflowCtx<A>, input: TInput): Promise<TOutput> | TOutput;
|
|
3481
|
+
}
|
|
3482
|
+
|
|
3372
3483
|
/**
|
|
3373
3484
|
* A non-durable, in-process `StateStore` for tests and local development.
|
|
3374
3485
|
* The shipped `@dudousxd/nestjs-durable-store` package re-exports an equivalent.
|
|
@@ -3458,4 +3569,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
|
|
|
3458
3569
|
onControl(handler: (msg: ControlMessage) => void): void;
|
|
3459
3570
|
}
|
|
3460
3571
|
|
|
3461
|
-
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DurableTopology, type DurableWebhook, DurableWorkflow, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, EventAccumulators, type EventBatchConfig, FatalError, GatherError, type GroupHealth, type Heartbeat, type HistoryEvent, InMemoryAdmissionBackend, InMemoryStateStore, InMemoryTransport, type InferSearchAttributes, type MetricsCollector, type MetricsSnapshot, type NamedTransport, NonDeterminismError, type PayloadCodec, type QueueConfig, QueueController, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, 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, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerHeartbeat, type WorkerStatus, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, applyAttributeQuery, attributeColumnFor, attributeOperand, bindWorkflowClass, breakpointToken, classifyWaiterToken, collectMetrics, createStepLogger, currentWorkflowCtx, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, indexWaitersByRun, matchesAttributes, normalizeAttributeRows, parseDuration, prevCronFireMs, readSearchAttributes, resolveRunWaiting, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, tenantGroup, workflowName };
|
|
3572
|
+
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, CONTROL_FLOW_SIGNAL, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DurableTopology, type DurableWebhook, DurableWorkflow, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, EventAccumulators, type EventBatchConfig, FatalError, GatherError, type GroupHealth, type Heartbeat, type HistoryEvent, InMemoryAdmissionBackend, InMemoryStateStore, InMemoryTransport, type InferSearchAttributes, type MetricsCollector, type MetricsSnapshot, type NamedTransport, NonDeterminismError, type PayloadCodec, type QueueConfig, QueueController, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, 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, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerHeartbeat, type WorkerStatus, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, applyAttributeQuery, attributeColumnFor, attributeOperand, bindWorkflowClass, breakpointToken, classifyWaiterToken, collectMetrics, createStepLogger, currentWorkflowCtx, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, indexWaitersByRun, isWorkflowControlFlowSignal, matchesAttributes, normalizeAttributeRows, parseDuration, prevCronFireMs, readSearchAttributes, resolveRunWaiting, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, tenantGroup, workflowName };
|
package/dist/index.d.ts
CHANGED
|
@@ -1749,6 +1749,59 @@ declare function runInWorkflowCtx<T>(ctx: WorkflowCtx, fn: () => T): T;
|
|
|
1749
1749
|
*/
|
|
1750
1750
|
declare function currentWorkflowCtx(): WorkflowCtx | undefined;
|
|
1751
1751
|
|
|
1752
|
+
/**
|
|
1753
|
+
* Cross-package, cross-runtime marker for engine CONTROL-FLOW signals — {@link WorkflowSuspended}
|
|
1754
|
+
* and {@link ContinueAsNew} (this package), plus the thin worker's {@link
|
|
1755
|
+
* import('@dudousxd/durable-worker').Suspend} (`@dudousxd/durable-worker`, the BullMQ
|
|
1756
|
+
* route-by-handler runtime). These are thrown by `WorkflowCtx`/`WorkflowContext` ops to unwind the
|
|
1757
|
+
* current turn — never real failures — so a workflow's `catch` block MUST rethrow them untouched.
|
|
1758
|
+
* Running a failure/cleanup path on a control-flow signal corrupts the run: it emits extra
|
|
1759
|
+
* `recordStep` commands into history that a subsequent replay didn't produce the first time,
|
|
1760
|
+
* surfacing as a `NonDeterminismError`/`NondeterminismError` on resume.
|
|
1761
|
+
*
|
|
1762
|
+
* `Symbol.for` (the GLOBAL registry), NOT a plain `Symbol()` — so a duplicate copy of this module
|
|
1763
|
+
* (pnpm peer-dependency multiplexing, a dual ESM/CJS load, or the SEPARATE `@dudousxd/durable-worker`
|
|
1764
|
+
* package declaring the same `Symbol.for` key locally) still collapses onto the SAME symbol. Same
|
|
1765
|
+
* rationale as `DURABLE_STEP_NAME` in `./step-name-symbol.ts`.
|
|
1766
|
+
*
|
|
1767
|
+
* Deliberately checked as a stamped property, NOT `instanceof` — `instanceof` only recognizes a
|
|
1768
|
+
* signal thrown by the SAME class the checking code imported, which fails across the in-process
|
|
1769
|
+
* engine (`@dudousxd/nestjs-durable-core`'s `WorkflowSuspended`/`ContinueAsNew`) and the thin worker
|
|
1770
|
+
* (`@dudousxd/durable-worker`'s `Suspend`) — two different classes for what is, from a workflow
|
|
1771
|
+
* author's catch block, the same "this isn't a real error, let it through" event.
|
|
1772
|
+
*
|
|
1773
|
+
* NOT designed to survive a serialization boundary (e.g. JSON over the wire) — these signals are
|
|
1774
|
+
* always thrown and caught in-process within a single replay turn, never (de)serialized, so a
|
|
1775
|
+
* stamped-but-not-cloneable property is sufficient.
|
|
1776
|
+
*/
|
|
1777
|
+
declare const CONTROL_FLOW_SIGNAL: unique symbol;
|
|
1778
|
+
/**
|
|
1779
|
+
* True for any engine control-flow signal (currently: {@link WorkflowSuspended}, {@link
|
|
1780
|
+
* ContinueAsNew}, and the thin worker's `Suspend`) — regardless of which runtime or module instance
|
|
1781
|
+
* threw it. Workflow `catch` blocks MUST rethrow these untouched; running a failure/cleanup path on
|
|
1782
|
+
* one corrupts the run's history (extra commands recorded during what replay will later see as a
|
|
1783
|
+
* suspend, not a failure) and the resumed replay dies with a non-determinism error.
|
|
1784
|
+
*
|
|
1785
|
+
* Deliberately NOT control-flow (do not add to this predicate):
|
|
1786
|
+
* - `Cancelled` (worker) / a cancelled run — a TERMINAL outcome the consumer may legitimately want
|
|
1787
|
+
* to observe and react to (e.g. release a lock), not a mid-turn unwind to rethrow untouched.
|
|
1788
|
+
* - `StepFailed` (worker) / an awaited step rejection reaching the engine — a REAL failure a
|
|
1789
|
+
* workflow's `catch` is meant to compensate for; misclassifying it as control-flow would swallow
|
|
1790
|
+
* genuine errors instead of protecting them.
|
|
1791
|
+
*
|
|
1792
|
+
* @example
|
|
1793
|
+
* ```ts
|
|
1794
|
+
* try {
|
|
1795
|
+
* await ctx.step('chargeCard', input);
|
|
1796
|
+
* } catch (error) {
|
|
1797
|
+
* if (isWorkflowControlFlowSignal(error)) throw error; // suspend/continue-as-new: rethrow as-is
|
|
1798
|
+
* await ctx.step('refund', input); // a REAL failure — safe to run cleanup here
|
|
1799
|
+
* throw error;
|
|
1800
|
+
* }
|
|
1801
|
+
* ```
|
|
1802
|
+
*/
|
|
1803
|
+
declare function isWorkflowControlFlowSignal(error: unknown): boolean;
|
|
1804
|
+
|
|
1752
1805
|
/**
|
|
1753
1806
|
* Back-compat alias of {@link WorkflowCtx}. `localStep` — the checkpointed in-process step primitive
|
|
1754
1807
|
* used for saga compensation — is now part of the public {@link WorkflowCtx}, so this type adds
|
|
@@ -2875,6 +2928,8 @@ declare class GatherError extends Error {
|
|
|
2875
2928
|
declare class WorkflowSuspended extends Error {
|
|
2876
2929
|
/** Epoch ms to auto-resume (durable sleep), or undefined when waiting on an external signal. */
|
|
2877
2930
|
readonly wakeAt?: number | undefined;
|
|
2931
|
+
/** Marks this as a control-flow signal — see {@link isWorkflowControlFlowSignal}. */
|
|
2932
|
+
readonly [CONTROL_FLOW_SIGNAL] = true;
|
|
2878
2933
|
constructor(wakeAt?: number);
|
|
2879
2934
|
}
|
|
2880
2935
|
/**
|
|
@@ -2884,6 +2939,8 @@ declare class WorkflowSuspended extends Error {
|
|
|
2884
2939
|
*/
|
|
2885
2940
|
declare class ContinueAsNew extends Error {
|
|
2886
2941
|
readonly input: unknown;
|
|
2942
|
+
/** Marks this as a control-flow signal — see {@link isWorkflowControlFlowSignal}. */
|
|
2943
|
+
readonly [CONTROL_FLOW_SIGNAL] = true;
|
|
2887
2944
|
constructor(input: unknown);
|
|
2888
2945
|
}
|
|
2889
2946
|
|
|
@@ -3369,6 +3426,60 @@ declare const STATE_STORE_CANONICAL: unique symbol;
|
|
|
3369
3426
|
declare const TRANSPORT_CANONICAL: unique symbol;
|
|
3370
3427
|
declare const DURABLE_OPTIONS_CANONICAL: unique symbol;
|
|
3371
3428
|
|
|
3429
|
+
/**
|
|
3430
|
+
* The OPT-IN declaration-site contract for a `@Workflow` class: `implements WorkflowHandler<TInput,
|
|
3431
|
+
* TOutput, A>` pins the class's `run(ctx, input)` signature against `TInput`/`TOutput`/`A` so a wrong
|
|
3432
|
+
* signature — a renamed method, swapped/missing param, wrong return type — is a compile error AT THE
|
|
3433
|
+
* CLASS instead of surfacing later as a runtime discovery failure (the `@Workflow` decorator finds no
|
|
3434
|
+
* `run` it recognizes) or a silently-wrong type flowing out of `ctx.child(ThisWorkflow, …)` /
|
|
3435
|
+
* `engine.start(ThisWorkflow, …)`. `A` also declares the run's {@link SearchAttributes} shape, so
|
|
3436
|
+
* `ctx.upsertSearchAttributes` is narrowed to it inside the workflow body — see
|
|
3437
|
+
* {@link SearchAttributesSchema} / {@link InferSearchAttributes} for pairing it with a `@Workflow({
|
|
3438
|
+
* searchAttributes })` schema.
|
|
3439
|
+
*
|
|
3440
|
+
* This is a TYPES-ONLY contract: nothing reads `implements WorkflowHandler` at runtime, registration
|
|
3441
|
+
* still goes through the `@Workflow` decorator + reflected metadata exactly as before, and a class
|
|
3442
|
+
* that doesn't implement it works exactly as it always has.
|
|
3443
|
+
*
|
|
3444
|
+
* IMPORTANT caveat: TypeScript does **not** contextually infer a method's parameter types from an
|
|
3445
|
+
* `implements` clause the way it does for e.g. an object literal assigned to a typed variable. The
|
|
3446
|
+
* class still has to annotate `ctx`/`input` itself — `implements` only CHECKS that what you wrote is
|
|
3447
|
+
* assignable to the interface; it doesn't write the annotations for you. Leaving `run`'s params
|
|
3448
|
+
* unannotated still leaves them `any`/inferred-from-usage, `implements` or not.
|
|
3449
|
+
*
|
|
3450
|
+
* @example
|
|
3451
|
+
* ```ts
|
|
3452
|
+
* import { z } from 'zod';
|
|
3453
|
+
* import { Workflow } from '@dudousxd/nestjs-durable';
|
|
3454
|
+
* import type { InferSearchAttributes, WorkflowCtx, WorkflowHandler } from '@dudousxd/nestjs-durable';
|
|
3455
|
+
*
|
|
3456
|
+
* const orderAttrs = z.object({
|
|
3457
|
+
* tier: z.enum(['free', 'pro']),
|
|
3458
|
+
* amount: z.number(),
|
|
3459
|
+
* });
|
|
3460
|
+
* type OrderAttrs = InferSearchAttributes<typeof orderAttrs>;
|
|
3461
|
+
*
|
|
3462
|
+
* interface CheckoutInput {
|
|
3463
|
+
* orderId: string;
|
|
3464
|
+
* }
|
|
3465
|
+
* interface CheckoutOutput {
|
|
3466
|
+
* receiptId: string;
|
|
3467
|
+
* }
|
|
3468
|
+
*
|
|
3469
|
+
* @Workflow({ name: 'checkout', searchAttributes: orderAttrs })
|
|
3470
|
+
* class CheckoutWorkflow implements WorkflowHandler<CheckoutInput, CheckoutOutput, OrderAttrs> {
|
|
3471
|
+
* async run(ctx: WorkflowCtx<OrderAttrs>, input: CheckoutInput): Promise<CheckoutOutput> {
|
|
3472
|
+
* await ctx.upsertSearchAttributes({ tier: 'pro', amount: 100 });
|
|
3473
|
+
* const receiptId = await ctx.step('charge-card', { orderId: input.orderId });
|
|
3474
|
+
* return { receiptId };
|
|
3475
|
+
* }
|
|
3476
|
+
* }
|
|
3477
|
+
* ```
|
|
3478
|
+
*/
|
|
3479
|
+
interface WorkflowHandler<TInput = unknown, TOutput = unknown, A extends SearchAttributes = SearchAttributes> {
|
|
3480
|
+
run(ctx: WorkflowCtx<A>, input: TInput): Promise<TOutput> | TOutput;
|
|
3481
|
+
}
|
|
3482
|
+
|
|
3372
3483
|
/**
|
|
3373
3484
|
* A non-durable, in-process `StateStore` for tests and local development.
|
|
3374
3485
|
* The shipped `@dudousxd/nestjs-durable-store` package re-exports an equivalent.
|
|
@@ -3458,4 +3569,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
|
|
|
3458
3569
|
onControl(handler: (msg: ControlMessage) => void): void;
|
|
3459
3570
|
}
|
|
3460
3571
|
|
|
3461
|
-
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DurableTopology, type DurableWebhook, DurableWorkflow, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, EventAccumulators, type EventBatchConfig, FatalError, GatherError, type GroupHealth, type Heartbeat, type HistoryEvent, InMemoryAdmissionBackend, InMemoryStateStore, InMemoryTransport, type InferSearchAttributes, type MetricsCollector, type MetricsSnapshot, type NamedTransport, NonDeterminismError, type PayloadCodec, type QueueConfig, QueueController, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, 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, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerHeartbeat, type WorkerStatus, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, applyAttributeQuery, attributeColumnFor, attributeOperand, bindWorkflowClass, breakpointToken, classifyWaiterToken, collectMetrics, createStepLogger, currentWorkflowCtx, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, indexWaitersByRun, matchesAttributes, normalizeAttributeRows, parseDuration, prevCronFireMs, readSearchAttributes, resolveRunWaiting, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, tenantGroup, workflowName };
|
|
3572
|
+
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, CONTROL_FLOW_SIGNAL, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DurableTopology, type DurableWebhook, DurableWorkflow, type EngineEvent, type EngineEventType, type EngineListener, Entities, type EntityConfig, type EntityHandler, type EntityHost, EventAccumulators, type EventBatchConfig, FatalError, GatherError, type GroupHealth, type Heartbeat, type HistoryEvent, InMemoryAdmissionBackend, InMemoryStateStore, InMemoryTransport, type InferSearchAttributes, type MetricsCollector, type MetricsSnapshot, type NamedTransport, NonDeterminismError, type PayloadCodec, type QueueConfig, QueueController, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, 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, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerHeartbeat, type WorkerStatus, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, applyAttributeQuery, attributeColumnFor, attributeOperand, bindWorkflowClass, breakpointToken, classifyWaiterToken, collectMetrics, createStepLogger, currentWorkflowCtx, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, indexWaitersByRun, isWorkflowControlFlowSignal, matchesAttributes, normalizeAttributeRows, parseDuration, prevCronFireMs, readSearchAttributes, resolveRunWaiting, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, tenantGroup, workflowName };
|
package/dist/index.js
CHANGED
|
@@ -173,6 +173,13 @@ function currentWorkflowCtx() {
|
|
|
173
173
|
}
|
|
174
174
|
__name(currentWorkflowCtx, "currentWorkflowCtx");
|
|
175
175
|
|
|
176
|
+
// src/control-flow-signal.ts
|
|
177
|
+
var CONTROL_FLOW_SIGNAL = Symbol.for("aviary:durable:control-flow");
|
|
178
|
+
function isWorkflowControlFlowSignal(error) {
|
|
179
|
+
return typeof error === "object" && error !== null && error[CONTROL_FLOW_SIGNAL] === true;
|
|
180
|
+
}
|
|
181
|
+
__name(isWorkflowControlFlowSignal, "isWorkflowControlFlowSignal");
|
|
182
|
+
|
|
176
183
|
// src/errors.ts
|
|
177
184
|
var FatalError = class extends Error {
|
|
178
185
|
static {
|
|
@@ -271,6 +278,8 @@ var WorkflowSuspended = class extends Error {
|
|
|
271
278
|
}
|
|
272
279
|
/** Epoch ms to auto-resume (durable sleep), or undefined when waiting on an external signal. */
|
|
273
280
|
wakeAt;
|
|
281
|
+
/** Marks this as a control-flow signal — see {@link isWorkflowControlFlowSignal}. */
|
|
282
|
+
[CONTROL_FLOW_SIGNAL] = true;
|
|
274
283
|
constructor(wakeAt) {
|
|
275
284
|
super("workflow suspended");
|
|
276
285
|
this.name = "WorkflowSuspended";
|
|
@@ -282,6 +291,8 @@ var ContinueAsNew = class extends Error {
|
|
|
282
291
|
__name(this, "ContinueAsNew");
|
|
283
292
|
}
|
|
284
293
|
input;
|
|
294
|
+
/** Marks this as a control-flow signal — see {@link isWorkflowControlFlowSignal}. */
|
|
295
|
+
[CONTROL_FLOW_SIGNAL] = true;
|
|
285
296
|
constructor(input) {
|
|
286
297
|
super("workflow continued as new"), this.input = input;
|
|
287
298
|
this.name = "ContinueAsNew";
|
|
@@ -5203,6 +5214,7 @@ var InMemoryTransport = class {
|
|
|
5203
5214
|
}
|
|
5204
5215
|
};
|
|
5205
5216
|
export {
|
|
5217
|
+
CONTROL_FLOW_SIGNAL,
|
|
5206
5218
|
CodecStateStore,
|
|
5207
5219
|
ContinueAsNew,
|
|
5208
5220
|
DURABLE_OPTIONS,
|
|
@@ -5248,6 +5260,7 @@ export {
|
|
|
5248
5260
|
eventPrefix,
|
|
5249
5261
|
eventToken,
|
|
5250
5262
|
indexWaitersByRun,
|
|
5263
|
+
isWorkflowControlFlowSignal,
|
|
5251
5264
|
matchesAttributes,
|
|
5252
5265
|
normalizeAttributeRows,
|
|
5253
5266
|
parseDuration,
|