@dudousxd/nestjs-durable-core 0.63.0 → 0.64.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 +92 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +80 -2
- package/dist/index.d.ts +80 -2
- package/dist/index.js +88 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -3177,8 +3177,22 @@ declare class WorkflowEngine {
|
|
|
3177
3177
|
* cancel flag stays too, re-derived from the status on any later re-drive regardless.
|
|
3178
3178
|
*/
|
|
3179
3179
|
private compensateAndCancel;
|
|
3180
|
-
/**
|
|
3180
|
+
/**
|
|
3181
|
+
* The run body, lease held + renewed by {@link execute}, wrapped in the registered
|
|
3182
|
+
* {@link runDurableExecution} wrappers so an observability scope covers ONE WHOLE TURN.
|
|
3183
|
+
*
|
|
3184
|
+
* The wrap goes here — around the entire turn — rather than tightly around the `fn(ctx, input)`
|
|
3185
|
+
* call, because the store writes that bracket the body (the `pending` → `running` transition, the
|
|
3186
|
+
* step checkpoints, the terminal `settleRun` update) are exactly the queries an operator wants
|
|
3187
|
+
* correlated to the turn that issued them. Narrowing the wrap to the body would leave them
|
|
3188
|
+
* uncorrelated for the sake of a purity that buys nothing.
|
|
3189
|
+
*
|
|
3190
|
+
* Only the TS path is wrapped. {@link runRemoteExecution} does not execute a body at all — it
|
|
3191
|
+
* dispatches a workflow task and awaits the worker's decision — so a scope opened there would
|
|
3192
|
+
* describe a dispatch, not an execution, and would mislead anyone reading the trace.
|
|
3193
|
+
*/
|
|
3181
3194
|
private runExecution;
|
|
3195
|
+
private runExecutionTurn;
|
|
3182
3196
|
/**
|
|
3183
3197
|
* Undo every registered saga compensation in strict reverse order — the shared unwind both the
|
|
3184
3198
|
* run-failure path (`runExecution`'s catch) and the compensating-cancel path
|
|
@@ -3670,6 +3684,70 @@ type RoutingResolution = RoutableResolution | BlockedResolution;
|
|
|
3670
3684
|
*/
|
|
3671
3685
|
declare function resolveRouting(handler: CapabilityRequirement, workers: readonly (RawWorkerDescriptor | WorkerDescriptor)[]): RoutingResolution;
|
|
3672
3686
|
|
|
3687
|
+
/**
|
|
3688
|
+
* Wrappers around the **real execution** of a unit of durable work — a workflow turn, or a step
|
|
3689
|
+
* handler body. Distinct from {@link StepInterceptor} (`engine.use`), which only sees the in-process
|
|
3690
|
+
* `localStep` primitives (`ctx.now`, `ctx.sideEffect`, `ctx.task`'s dispatch step, saga
|
|
3691
|
+
* compensations): a user's `ctx.step` is ALWAYS dispatched, so its handler runs inside a transport
|
|
3692
|
+
* callback or a worker process where no engine is in scope at all.
|
|
3693
|
+
*
|
|
3694
|
+
* That is exactly why this registry is process-level rather than per-engine. `runStepHandler` is a
|
|
3695
|
+
* free function every transport shares, and a thin worker (`DurableModule` with a `connection` and
|
|
3696
|
+
* no `store`) holds no `WorkflowEngine` to hang a hook off. A per-engine registry could not reach
|
|
3697
|
+
* either, so the seam that covers every deployment shape has to sit above the engine.
|
|
3698
|
+
*
|
|
3699
|
+
* The intended consumer is an observability bridge (Telescope, OTel, a logger) that needs to
|
|
3700
|
+
* establish an ambient scope — an AsyncLocalStorage batch, a span — that the executing code records
|
|
3701
|
+
* into. It is deliberately NOT a transform point: see {@link runDurableExecution}.
|
|
3702
|
+
*/
|
|
3703
|
+
/** The unit of durable work a wrapper is being invoked around. */
|
|
3704
|
+
interface DurableExecution {
|
|
3705
|
+
/** `'workflow'` = one turn of a run's body; `'step'` = one step handler body. */
|
|
3706
|
+
readonly unit: 'workflow' | 'step';
|
|
3707
|
+
readonly runId: string;
|
|
3708
|
+
/** The workflow name. Present on a turn; a dispatched step task does not carry it on the wire. */
|
|
3709
|
+
readonly workflow: string | undefined;
|
|
3710
|
+
/** The step name, for `unit: 'step'`. Undefined for a turn. */
|
|
3711
|
+
readonly name: string | undefined;
|
|
3712
|
+
/** The step's logical position within the run, for `unit: 'step'`. */
|
|
3713
|
+
readonly seq: number | undefined;
|
|
3714
|
+
/** 1-based dispatch attempt, when the task carries one. */
|
|
3715
|
+
readonly attempt: number | undefined;
|
|
3716
|
+
}
|
|
3717
|
+
/**
|
|
3718
|
+
* Wraps one unit of durable work. Call `next()` to run the body (or the next wrapper). Whatever the
|
|
3719
|
+
* wrapper returns or throws is discarded — see {@link runDurableExecution} for why.
|
|
3720
|
+
*/
|
|
3721
|
+
type DurableExecutionWrapper = (execution: DurableExecution, next: () => Promise<unknown>) => Promise<unknown>;
|
|
3722
|
+
/**
|
|
3723
|
+
* Register a {@link DurableExecutionWrapper}. Returns an unregister function.
|
|
3724
|
+
*
|
|
3725
|
+
* Registering is the ONLY cost an unused hook imposes: with an empty registry
|
|
3726
|
+
* {@link runDurableExecution} returns the body's own promise without allocating a chain, so a host
|
|
3727
|
+
* that wires no observability pays nothing at all on the execution path.
|
|
3728
|
+
*/
|
|
3729
|
+
declare function useDurableExecution(wrapper: DurableExecutionWrapper): () => void;
|
|
3730
|
+
/** Drop every registered wrapper. For tests that must not leak a wrapper into the next file. */
|
|
3731
|
+
declare function clearDurableExecutionWrappers(): void;
|
|
3732
|
+
/** Whether any wrapper is registered — lets a hot path skip building an execution descriptor. */
|
|
3733
|
+
declare function hasDurableExecutionWrappers(): boolean;
|
|
3734
|
+
/**
|
|
3735
|
+
* Run `body` inside every registered wrapper and settle with **the body's own outcome**.
|
|
3736
|
+
*
|
|
3737
|
+
* The wrappers' return values and throws are deliberately ignored. An observer that misbehaves —
|
|
3738
|
+
* returns early without calling `next()` is the one case we cannot paper over, but one that throws
|
|
3739
|
+
* *after* the body settled, or swallows the body's error and returns normally, is common enough in
|
|
3740
|
+
* telemetry code — must not be able to change what the workflow saw. A wrapper that turned a failed
|
|
3741
|
+
* step into a completed one would corrupt the run's history and its checkpoints, which is a far
|
|
3742
|
+
* worse failure than a missing trace. This is the same reasoning the bullmq/schedule Telescope
|
|
3743
|
+
* watchers apply when they re-throw the host's error rather than swallowing it, pushed down into
|
|
3744
|
+
* the seam so every wrapper gets it for free instead of having to remember.
|
|
3745
|
+
*
|
|
3746
|
+
* The one unrecoverable case is a wrapper that never calls `next()`: the body did not run, so there
|
|
3747
|
+
* is no outcome to return and we throw rather than invent one.
|
|
3748
|
+
*/
|
|
3749
|
+
declare function runDurableExecution<T>(execution: DurableExecution, body: () => Promise<T>): Promise<T>;
|
|
3750
|
+
|
|
3673
3751
|
/** Canonical step id — the stable identity of a step within a run, used for dedupe and
|
|
3674
3752
|
* correlation. The format is part of the cross-language wire contract (Python builds the same). */
|
|
3675
3753
|
declare function stepId(runId: string, seq: number): string;
|
|
@@ -4345,4 +4423,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
|
|
|
4345
4423
|
onControl(handler: (msg: ControlMessage) => void): void;
|
|
4346
4424
|
}
|
|
4347
4425
|
|
|
4348
|
-
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DispatchDiagnostics, type DispatchPlan, type DurableTopology, type DurableWebhook, DurableWorkflow, 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 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 PayloadCodec, type QueueConfig, QueueController, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, 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 WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, WorkflowBlocked, 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, canRoute, capableWorkers, classifyWaiterToken, collectMetrics, controlPlaneDescriptor, createStepLogger, currentStep, currentWorkflowCtx, debug, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, heartbeatStatus, indexWaitersByRun, info, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, log, matchesAttributes, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, parseDuration, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runInStepLogger, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, warn, workflowName };
|
|
4426
|
+
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, 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 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 PayloadCodec, type QueueConfig, QueueController, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, 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 WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, WorkflowBlocked, 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, canRoute, capableWorkers, classifyWaiterToken, clearDurableExecutionWrappers, collectMetrics, controlPlaneDescriptor, createStepLogger, currentStep, currentWorkflowCtx, debug, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, hasDurableExecutionWrappers, heartbeatStatus, indexWaitersByRun, info, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, log, matchesAttributes, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, parseDuration, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runDurableExecution, runInStepLogger, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };
|
package/dist/index.d.ts
CHANGED
|
@@ -3177,8 +3177,22 @@ declare class WorkflowEngine {
|
|
|
3177
3177
|
* cancel flag stays too, re-derived from the status on any later re-drive regardless.
|
|
3178
3178
|
*/
|
|
3179
3179
|
private compensateAndCancel;
|
|
3180
|
-
/**
|
|
3180
|
+
/**
|
|
3181
|
+
* The run body, lease held + renewed by {@link execute}, wrapped in the registered
|
|
3182
|
+
* {@link runDurableExecution} wrappers so an observability scope covers ONE WHOLE TURN.
|
|
3183
|
+
*
|
|
3184
|
+
* The wrap goes here — around the entire turn — rather than tightly around the `fn(ctx, input)`
|
|
3185
|
+
* call, because the store writes that bracket the body (the `pending` → `running` transition, the
|
|
3186
|
+
* step checkpoints, the terminal `settleRun` update) are exactly the queries an operator wants
|
|
3187
|
+
* correlated to the turn that issued them. Narrowing the wrap to the body would leave them
|
|
3188
|
+
* uncorrelated for the sake of a purity that buys nothing.
|
|
3189
|
+
*
|
|
3190
|
+
* Only the TS path is wrapped. {@link runRemoteExecution} does not execute a body at all — it
|
|
3191
|
+
* dispatches a workflow task and awaits the worker's decision — so a scope opened there would
|
|
3192
|
+
* describe a dispatch, not an execution, and would mislead anyone reading the trace.
|
|
3193
|
+
*/
|
|
3181
3194
|
private runExecution;
|
|
3195
|
+
private runExecutionTurn;
|
|
3182
3196
|
/**
|
|
3183
3197
|
* Undo every registered saga compensation in strict reverse order — the shared unwind both the
|
|
3184
3198
|
* run-failure path (`runExecution`'s catch) and the compensating-cancel path
|
|
@@ -3670,6 +3684,70 @@ type RoutingResolution = RoutableResolution | BlockedResolution;
|
|
|
3670
3684
|
*/
|
|
3671
3685
|
declare function resolveRouting(handler: CapabilityRequirement, workers: readonly (RawWorkerDescriptor | WorkerDescriptor)[]): RoutingResolution;
|
|
3672
3686
|
|
|
3687
|
+
/**
|
|
3688
|
+
* Wrappers around the **real execution** of a unit of durable work — a workflow turn, or a step
|
|
3689
|
+
* handler body. Distinct from {@link StepInterceptor} (`engine.use`), which only sees the in-process
|
|
3690
|
+
* `localStep` primitives (`ctx.now`, `ctx.sideEffect`, `ctx.task`'s dispatch step, saga
|
|
3691
|
+
* compensations): a user's `ctx.step` is ALWAYS dispatched, so its handler runs inside a transport
|
|
3692
|
+
* callback or a worker process where no engine is in scope at all.
|
|
3693
|
+
*
|
|
3694
|
+
* That is exactly why this registry is process-level rather than per-engine. `runStepHandler` is a
|
|
3695
|
+
* free function every transport shares, and a thin worker (`DurableModule` with a `connection` and
|
|
3696
|
+
* no `store`) holds no `WorkflowEngine` to hang a hook off. A per-engine registry could not reach
|
|
3697
|
+
* either, so the seam that covers every deployment shape has to sit above the engine.
|
|
3698
|
+
*
|
|
3699
|
+
* The intended consumer is an observability bridge (Telescope, OTel, a logger) that needs to
|
|
3700
|
+
* establish an ambient scope — an AsyncLocalStorage batch, a span — that the executing code records
|
|
3701
|
+
* into. It is deliberately NOT a transform point: see {@link runDurableExecution}.
|
|
3702
|
+
*/
|
|
3703
|
+
/** The unit of durable work a wrapper is being invoked around. */
|
|
3704
|
+
interface DurableExecution {
|
|
3705
|
+
/** `'workflow'` = one turn of a run's body; `'step'` = one step handler body. */
|
|
3706
|
+
readonly unit: 'workflow' | 'step';
|
|
3707
|
+
readonly runId: string;
|
|
3708
|
+
/** The workflow name. Present on a turn; a dispatched step task does not carry it on the wire. */
|
|
3709
|
+
readonly workflow: string | undefined;
|
|
3710
|
+
/** The step name, for `unit: 'step'`. Undefined for a turn. */
|
|
3711
|
+
readonly name: string | undefined;
|
|
3712
|
+
/** The step's logical position within the run, for `unit: 'step'`. */
|
|
3713
|
+
readonly seq: number | undefined;
|
|
3714
|
+
/** 1-based dispatch attempt, when the task carries one. */
|
|
3715
|
+
readonly attempt: number | undefined;
|
|
3716
|
+
}
|
|
3717
|
+
/**
|
|
3718
|
+
* Wraps one unit of durable work. Call `next()` to run the body (or the next wrapper). Whatever the
|
|
3719
|
+
* wrapper returns or throws is discarded — see {@link runDurableExecution} for why.
|
|
3720
|
+
*/
|
|
3721
|
+
type DurableExecutionWrapper = (execution: DurableExecution, next: () => Promise<unknown>) => Promise<unknown>;
|
|
3722
|
+
/**
|
|
3723
|
+
* Register a {@link DurableExecutionWrapper}. Returns an unregister function.
|
|
3724
|
+
*
|
|
3725
|
+
* Registering is the ONLY cost an unused hook imposes: with an empty registry
|
|
3726
|
+
* {@link runDurableExecution} returns the body's own promise without allocating a chain, so a host
|
|
3727
|
+
* that wires no observability pays nothing at all on the execution path.
|
|
3728
|
+
*/
|
|
3729
|
+
declare function useDurableExecution(wrapper: DurableExecutionWrapper): () => void;
|
|
3730
|
+
/** Drop every registered wrapper. For tests that must not leak a wrapper into the next file. */
|
|
3731
|
+
declare function clearDurableExecutionWrappers(): void;
|
|
3732
|
+
/** Whether any wrapper is registered — lets a hot path skip building an execution descriptor. */
|
|
3733
|
+
declare function hasDurableExecutionWrappers(): boolean;
|
|
3734
|
+
/**
|
|
3735
|
+
* Run `body` inside every registered wrapper and settle with **the body's own outcome**.
|
|
3736
|
+
*
|
|
3737
|
+
* The wrappers' return values and throws are deliberately ignored. An observer that misbehaves —
|
|
3738
|
+
* returns early without calling `next()` is the one case we cannot paper over, but one that throws
|
|
3739
|
+
* *after* the body settled, or swallows the body's error and returns normally, is common enough in
|
|
3740
|
+
* telemetry code — must not be able to change what the workflow saw. A wrapper that turned a failed
|
|
3741
|
+
* step into a completed one would corrupt the run's history and its checkpoints, which is a far
|
|
3742
|
+
* worse failure than a missing trace. This is the same reasoning the bullmq/schedule Telescope
|
|
3743
|
+
* watchers apply when they re-throw the host's error rather than swallowing it, pushed down into
|
|
3744
|
+
* the seam so every wrapper gets it for free instead of having to remember.
|
|
3745
|
+
*
|
|
3746
|
+
* The one unrecoverable case is a wrapper that never calls `next()`: the body did not run, so there
|
|
3747
|
+
* is no outcome to return and we throw rather than invent one.
|
|
3748
|
+
*/
|
|
3749
|
+
declare function runDurableExecution<T>(execution: DurableExecution, body: () => Promise<T>): Promise<T>;
|
|
3750
|
+
|
|
3673
3751
|
/** Canonical step id — the stable identity of a step within a run, used for dedupe and
|
|
3674
3752
|
* correlation. The format is part of the cross-language wire contract (Python builds the same). */
|
|
3675
3753
|
declare function stepId(runId: string, seq: number): string;
|
|
@@ -4345,4 +4423,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
|
|
|
4345
4423
|
onControl(handler: (msg: ControlMessage) => void): void;
|
|
4346
4424
|
}
|
|
4347
4425
|
|
|
4348
|
-
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DispatchDiagnostics, type DispatchPlan, type DurableTopology, type DurableWebhook, DurableWorkflow, 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 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 PayloadCodec, type QueueConfig, QueueController, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, 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 WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, WorkflowBlocked, 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, canRoute, capableWorkers, classifyWaiterToken, collectMetrics, controlPlaneDescriptor, createStepLogger, currentStep, currentWorkflowCtx, debug, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, heartbeatStatus, indexWaitersByRun, info, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, log, matchesAttributes, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, parseDuration, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runInStepLogger, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, warn, workflowName };
|
|
4426
|
+
export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AttributeFilter, type AttributeOp, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, 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 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 PayloadCodec, type QueueConfig, QueueController, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, 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 WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, WorkflowBlocked, 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, canRoute, capableWorkers, classifyWaiterToken, clearDurableExecutionWrappers, collectMetrics, controlPlaneDescriptor, createStepLogger, currentStep, currentWorkflowCtx, debug, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, hasDurableExecutionWrappers, heartbeatStatus, indexWaitersByRun, info, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, log, matchesAttributes, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, parseDuration, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runDurableExecution, runInStepLogger, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };
|
package/dist/index.js
CHANGED
|
@@ -481,6 +481,57 @@ function backoffDelay(attempt, options) {
|
|
|
481
481
|
}
|
|
482
482
|
__name(backoffDelay, "backoffDelay");
|
|
483
483
|
|
|
484
|
+
// src/execution-hooks.ts
|
|
485
|
+
var wrappers = [];
|
|
486
|
+
function useDurableExecution(wrapper) {
|
|
487
|
+
wrappers.push(wrapper);
|
|
488
|
+
return () => {
|
|
489
|
+
const i = wrappers.indexOf(wrapper);
|
|
490
|
+
if (i >= 0) wrappers.splice(i, 1);
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
__name(useDurableExecution, "useDurableExecution");
|
|
494
|
+
function clearDurableExecutionWrappers() {
|
|
495
|
+
wrappers.length = 0;
|
|
496
|
+
}
|
|
497
|
+
__name(clearDurableExecutionWrappers, "clearDurableExecutionWrappers");
|
|
498
|
+
function hasDurableExecutionWrappers() {
|
|
499
|
+
return wrappers.length > 0;
|
|
500
|
+
}
|
|
501
|
+
__name(hasDurableExecutionWrappers, "hasDurableExecutionWrappers");
|
|
502
|
+
async function runDurableExecution(execution, body) {
|
|
503
|
+
if (wrappers.length === 0) return body();
|
|
504
|
+
let outcome;
|
|
505
|
+
const inner = /* @__PURE__ */ __name(async () => {
|
|
506
|
+
try {
|
|
507
|
+
const value = await body();
|
|
508
|
+
outcome = {
|
|
509
|
+
ok: true,
|
|
510
|
+
value
|
|
511
|
+
};
|
|
512
|
+
return value;
|
|
513
|
+
} catch (error2) {
|
|
514
|
+
outcome = {
|
|
515
|
+
ok: false,
|
|
516
|
+
error: error2
|
|
517
|
+
};
|
|
518
|
+
throw error2;
|
|
519
|
+
}
|
|
520
|
+
}, "inner");
|
|
521
|
+
const chain = wrappers.reduceRight((next, wrapper) => () => wrapper(execution, next), inner);
|
|
522
|
+
try {
|
|
523
|
+
await chain();
|
|
524
|
+
} catch (error2) {
|
|
525
|
+
if (outcome === void 0) throw error2;
|
|
526
|
+
}
|
|
527
|
+
if (outcome === void 0) {
|
|
528
|
+
throw new Error("a durable execution wrapper returned without calling next() \u2014 the unit of work never ran");
|
|
529
|
+
}
|
|
530
|
+
if (outcome.ok) return outcome.value;
|
|
531
|
+
throw outcome.error;
|
|
532
|
+
}
|
|
533
|
+
__name(runDurableExecution, "runDurableExecution");
|
|
534
|
+
|
|
484
535
|
// src/step-logger.ts
|
|
485
536
|
function withDuration(start, now, data) {
|
|
486
537
|
if (data && typeof data === "object" && "durationMs" in data) {
|
|
@@ -622,7 +673,14 @@ async function runStepHandler(task, handler) {
|
|
|
622
673
|
} : result, "withEvents");
|
|
623
674
|
try {
|
|
624
675
|
const logger = createStepLogger(events, Date.now);
|
|
625
|
-
const output = await
|
|
676
|
+
const output = await runDurableExecution({
|
|
677
|
+
unit: "step",
|
|
678
|
+
runId: task.runId,
|
|
679
|
+
workflow: void 0,
|
|
680
|
+
name: task.name,
|
|
681
|
+
seq: task.seq,
|
|
682
|
+
attempt: task.attempt
|
|
683
|
+
}, async () => runInStepLogger(logger, () => handler(task.input, logger)));
|
|
626
684
|
return withEvents({
|
|
627
685
|
...base,
|
|
628
686
|
status: "completed",
|
|
@@ -4524,8 +4582,31 @@ var WorkflowEngine = class {
|
|
|
4524
4582
|
error: error2
|
|
4525
4583
|
};
|
|
4526
4584
|
}
|
|
4527
|
-
/**
|
|
4528
|
-
|
|
4585
|
+
/**
|
|
4586
|
+
* The run body, lease held + renewed by {@link execute}, wrapped in the registered
|
|
4587
|
+
* {@link runDurableExecution} wrappers so an observability scope covers ONE WHOLE TURN.
|
|
4588
|
+
*
|
|
4589
|
+
* The wrap goes here — around the entire turn — rather than tightly around the `fn(ctx, input)`
|
|
4590
|
+
* call, because the store writes that bracket the body (the `pending` → `running` transition, the
|
|
4591
|
+
* step checkpoints, the terminal `settleRun` update) are exactly the queries an operator wants
|
|
4592
|
+
* correlated to the turn that issued them. Narrowing the wrap to the body would leave them
|
|
4593
|
+
* uncorrelated for the sake of a purity that buys nothing.
|
|
4594
|
+
*
|
|
4595
|
+
* Only the TS path is wrapped. {@link runRemoteExecution} does not execute a body at all — it
|
|
4596
|
+
* dispatches a workflow task and awaits the worker's decision — so a scope opened there would
|
|
4597
|
+
* describe a dispatch, not an execution, and would mislead anyone reading the trace.
|
|
4598
|
+
*/
|
|
4599
|
+
runExecution(run, fn, registered) {
|
|
4600
|
+
return runDurableExecution({
|
|
4601
|
+
unit: "workflow",
|
|
4602
|
+
runId: run.id,
|
|
4603
|
+
workflow: run.workflow,
|
|
4604
|
+
name: void 0,
|
|
4605
|
+
seq: void 0,
|
|
4606
|
+
attempt: void 0
|
|
4607
|
+
}, () => this.runExecutionTurn(run, fn, registered));
|
|
4608
|
+
}
|
|
4609
|
+
async runExecutionTurn(run, fn, registered) {
|
|
4529
4610
|
if (run.status === "cancelling") this.cancelRequested.add(run.id);
|
|
4530
4611
|
if (run.status === "pending") {
|
|
4531
4612
|
await this.store.updateRun(run.id, {
|
|
@@ -6284,6 +6365,7 @@ export {
|
|
|
6284
6365
|
canRoute,
|
|
6285
6366
|
capableWorkers,
|
|
6286
6367
|
classifyWaiterToken,
|
|
6368
|
+
clearDurableExecutionWrappers,
|
|
6287
6369
|
collectMetrics,
|
|
6288
6370
|
controlPlaneDescriptor,
|
|
6289
6371
|
createStepLogger,
|
|
@@ -6297,6 +6379,7 @@ export {
|
|
|
6297
6379
|
eventNameOf,
|
|
6298
6380
|
eventPrefix,
|
|
6299
6381
|
eventToken,
|
|
6382
|
+
hasDurableExecutionWrappers,
|
|
6300
6383
|
heartbeatStatus,
|
|
6301
6384
|
indexWaitersByRun,
|
|
6302
6385
|
info,
|
|
@@ -6316,6 +6399,7 @@ export {
|
|
|
6316
6399
|
requiredCapabilities,
|
|
6317
6400
|
resolveRouting,
|
|
6318
6401
|
resolveRunWaiting,
|
|
6402
|
+
runDurableExecution,
|
|
6319
6403
|
runInStepLogger,
|
|
6320
6404
|
runInWorkflowCtx,
|
|
6321
6405
|
runSchedules,
|
|
@@ -6330,6 +6414,7 @@ export {
|
|
|
6330
6414
|
subEvent,
|
|
6331
6415
|
subProcess,
|
|
6332
6416
|
tenantGroup,
|
|
6417
|
+
useDurableExecution,
|
|
6333
6418
|
warn,
|
|
6334
6419
|
workflowName
|
|
6335
6420
|
};
|