@dudousxd/nestjs-durable-core 0.62.1 → 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 +99 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +121 -3
- package/dist/index.d.ts +121 -3
- package/dist/index.js +95 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -627,6 +627,24 @@ interface WorkflowRun {
|
|
|
627
627
|
* store persists it as `'default'`. Read paths (dashboard, `getRun`) are NOT namespace-scoped.
|
|
628
628
|
*/
|
|
629
629
|
namespace?: string | undefined;
|
|
630
|
+
/**
|
|
631
|
+
* The npm package that DECLARED this run's workflow — e.g. `@dudousxd/nestjs-catalog-pipeline` for
|
|
632
|
+
* a workflow shipped by a library, or the host app's own `package.json` `name` for one written in
|
|
633
|
+
* the app. This is a CODE-PROVENANCE axis ("which lib owns this body"), NOT a tenancy axis — for
|
|
634
|
+
* that, see {@link namespace}.
|
|
635
|
+
*
|
|
636
|
+
* Stamped at creation from the workflow's registration, exactly as {@link namespace} is stamped
|
|
637
|
+
* from the creating engine. It is DERIVED, never caller input: `StartOptions` has no `origin`, so
|
|
638
|
+
* nothing a caller passes to `start` can make a run claim another lib's name.
|
|
639
|
+
*
|
|
640
|
+
* `undefined` means UNKNOWN — never "the app". It is what you get for a run created before this
|
|
641
|
+
* field existed, for a registration path that carries no origin (`registerRemote`, convention
|
|
642
|
+
* routing, a synthesized remote child, or a bare `engine.register` with no `origin` option), and
|
|
643
|
+
* for a workflow whose declaring package could not be resolved with confidence. A wrong origin is
|
|
644
|
+
* worse than an absent one: a filter that silently drops runs looks exactly like runs that never
|
|
645
|
+
* existed, so callers must render unknown as unknown and never fold it into a real package.
|
|
646
|
+
*/
|
|
647
|
+
origin?: string | undefined;
|
|
630
648
|
/**
|
|
631
649
|
* Dispatch priority for a REMOTE run (one advanced by a {@link WorkflowExecutor} over a broker):
|
|
632
650
|
* carried onto each {@link WorkflowTask} so an urgent child workflow can jump ahead of enqueued
|
|
@@ -1045,6 +1063,15 @@ interface RunQuery {
|
|
|
1045
1063
|
attributes?: AttributeFilter[] | undefined;
|
|
1046
1064
|
/** Restrict to runs in this namespace (exact match), ANDed with the other predicates. */
|
|
1047
1065
|
namespace?: string | undefined;
|
|
1066
|
+
/**
|
|
1067
|
+
* Restrict to runs whose workflow was declared by this package (exact match against
|
|
1068
|
+
* {@link WorkflowRun.origin}), ANDed with the other predicates.
|
|
1069
|
+
*
|
|
1070
|
+
* A run with NO origin (unknown — see the field) matches no `origin` value at all, so a UI facet
|
|
1071
|
+
* built on this must keep an "all origins" option: filtering by any single package silently hides
|
|
1072
|
+
* every unattributed run, which reads to an operator as "those runs do not exist".
|
|
1073
|
+
*/
|
|
1074
|
+
origin?: string | undefined;
|
|
1048
1075
|
limit?: number | undefined;
|
|
1049
1076
|
offset?: number | undefined;
|
|
1050
1077
|
}
|
|
@@ -2262,7 +2289,14 @@ declare class EventAccumulators {
|
|
|
2262
2289
|
}
|
|
2263
2290
|
|
|
2264
2291
|
type WorkflowFn = (ctx: InternalWorkflowCtx, input: unknown) => Promise<unknown>;
|
|
2265
|
-
/**
|
|
2292
|
+
/**
|
|
2293
|
+
* Options for {@link WorkflowEngine.start}.
|
|
2294
|
+
*
|
|
2295
|
+
* Note the absence of `origin`: {@link WorkflowRun.origin} says which PACKAGE declared the workflow,
|
|
2296
|
+
* which is a property of the registered code, not of whoever started it. It is taken from the
|
|
2297
|
+
* registration and nothing here can override it — otherwise one caller could label its runs as
|
|
2298
|
+
* another lib's, and an origin filter would quietly lie.
|
|
2299
|
+
*/
|
|
2266
2300
|
interface StartOptions {
|
|
2267
2301
|
/** Run-scoped tags, merged with the workflow's static `@Workflow({ tags })` onto the run. */
|
|
2268
2302
|
tags?: string[] | undefined;
|
|
@@ -2596,6 +2630,12 @@ declare class WorkflowEngine {
|
|
|
2596
2630
|
/** Capabilities a live worker must advertise to run this workflow's turns (handshake §7.5).
|
|
2597
2631
|
* Only meaningful with `group`/`executor` (a remote/group-served workflow). Absent = runs anywhere. */
|
|
2598
2632
|
requires?: string[] | undefined;
|
|
2633
|
+
/** The package that DECLARED this workflow, stamped onto every run started from it (see
|
|
2634
|
+
* {@link WorkflowRun.origin}). Supplied by the registering integration — `@dudousxd/nestjs-durable`
|
|
2635
|
+
* derives it from the `@Workflow` class's declaring file — never by whoever calls `start`. Omit
|
|
2636
|
+
* when it cannot be derived with confidence: absent means UNKNOWN, and an absent origin is far
|
|
2637
|
+
* cheaper to live with than a wrong one. */
|
|
2638
|
+
origin?: string | undefined;
|
|
2599
2639
|
}): void;
|
|
2600
2640
|
/**
|
|
2601
2641
|
* The retained in-process body for `name@version`, for an IN-APP worker that consumes this engine's
|
|
@@ -3137,8 +3177,22 @@ declare class WorkflowEngine {
|
|
|
3137
3177
|
* cancel flag stays too, re-derived from the status on any later re-drive regardless.
|
|
3138
3178
|
*/
|
|
3139
3179
|
private compensateAndCancel;
|
|
3140
|
-
/**
|
|
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
|
+
*/
|
|
3141
3194
|
private runExecution;
|
|
3195
|
+
private runExecutionTurn;
|
|
3142
3196
|
/**
|
|
3143
3197
|
* Undo every registered saga compensation in strict reverse order — the shared unwind both the
|
|
3144
3198
|
* run-failure path (`runExecution`'s catch) and the compensating-cancel path
|
|
@@ -3630,6 +3684,70 @@ type RoutingResolution = RoutableResolution | BlockedResolution;
|
|
|
3630
3684
|
*/
|
|
3631
3685
|
declare function resolveRouting(handler: CapabilityRequirement, workers: readonly (RawWorkerDescriptor | WorkerDescriptor)[]): RoutingResolution;
|
|
3632
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
|
+
|
|
3633
3751
|
/** Canonical step id — the stable identity of a step within a run, used for dedupe and
|
|
3634
3752
|
* correlation. The format is part of the cross-language wire contract (Python builds the same). */
|
|
3635
3753
|
declare function stepId(runId: string, seq: number): string;
|
|
@@ -4305,4 +4423,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
|
|
|
4305
4423
|
onControl(handler: (msg: ControlMessage) => void): void;
|
|
4306
4424
|
}
|
|
4307
4425
|
|
|
4308
|
-
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
|
@@ -627,6 +627,24 @@ interface WorkflowRun {
|
|
|
627
627
|
* store persists it as `'default'`. Read paths (dashboard, `getRun`) are NOT namespace-scoped.
|
|
628
628
|
*/
|
|
629
629
|
namespace?: string | undefined;
|
|
630
|
+
/**
|
|
631
|
+
* The npm package that DECLARED this run's workflow — e.g. `@dudousxd/nestjs-catalog-pipeline` for
|
|
632
|
+
* a workflow shipped by a library, or the host app's own `package.json` `name` for one written in
|
|
633
|
+
* the app. This is a CODE-PROVENANCE axis ("which lib owns this body"), NOT a tenancy axis — for
|
|
634
|
+
* that, see {@link namespace}.
|
|
635
|
+
*
|
|
636
|
+
* Stamped at creation from the workflow's registration, exactly as {@link namespace} is stamped
|
|
637
|
+
* from the creating engine. It is DERIVED, never caller input: `StartOptions` has no `origin`, so
|
|
638
|
+
* nothing a caller passes to `start` can make a run claim another lib's name.
|
|
639
|
+
*
|
|
640
|
+
* `undefined` means UNKNOWN — never "the app". It is what you get for a run created before this
|
|
641
|
+
* field existed, for a registration path that carries no origin (`registerRemote`, convention
|
|
642
|
+
* routing, a synthesized remote child, or a bare `engine.register` with no `origin` option), and
|
|
643
|
+
* for a workflow whose declaring package could not be resolved with confidence. A wrong origin is
|
|
644
|
+
* worse than an absent one: a filter that silently drops runs looks exactly like runs that never
|
|
645
|
+
* existed, so callers must render unknown as unknown and never fold it into a real package.
|
|
646
|
+
*/
|
|
647
|
+
origin?: string | undefined;
|
|
630
648
|
/**
|
|
631
649
|
* Dispatch priority for a REMOTE run (one advanced by a {@link WorkflowExecutor} over a broker):
|
|
632
650
|
* carried onto each {@link WorkflowTask} so an urgent child workflow can jump ahead of enqueued
|
|
@@ -1045,6 +1063,15 @@ interface RunQuery {
|
|
|
1045
1063
|
attributes?: AttributeFilter[] | undefined;
|
|
1046
1064
|
/** Restrict to runs in this namespace (exact match), ANDed with the other predicates. */
|
|
1047
1065
|
namespace?: string | undefined;
|
|
1066
|
+
/**
|
|
1067
|
+
* Restrict to runs whose workflow was declared by this package (exact match against
|
|
1068
|
+
* {@link WorkflowRun.origin}), ANDed with the other predicates.
|
|
1069
|
+
*
|
|
1070
|
+
* A run with NO origin (unknown — see the field) matches no `origin` value at all, so a UI facet
|
|
1071
|
+
* built on this must keep an "all origins" option: filtering by any single package silently hides
|
|
1072
|
+
* every unattributed run, which reads to an operator as "those runs do not exist".
|
|
1073
|
+
*/
|
|
1074
|
+
origin?: string | undefined;
|
|
1048
1075
|
limit?: number | undefined;
|
|
1049
1076
|
offset?: number | undefined;
|
|
1050
1077
|
}
|
|
@@ -2262,7 +2289,14 @@ declare class EventAccumulators {
|
|
|
2262
2289
|
}
|
|
2263
2290
|
|
|
2264
2291
|
type WorkflowFn = (ctx: InternalWorkflowCtx, input: unknown) => Promise<unknown>;
|
|
2265
|
-
/**
|
|
2292
|
+
/**
|
|
2293
|
+
* Options for {@link WorkflowEngine.start}.
|
|
2294
|
+
*
|
|
2295
|
+
* Note the absence of `origin`: {@link WorkflowRun.origin} says which PACKAGE declared the workflow,
|
|
2296
|
+
* which is a property of the registered code, not of whoever started it. It is taken from the
|
|
2297
|
+
* registration and nothing here can override it — otherwise one caller could label its runs as
|
|
2298
|
+
* another lib's, and an origin filter would quietly lie.
|
|
2299
|
+
*/
|
|
2266
2300
|
interface StartOptions {
|
|
2267
2301
|
/** Run-scoped tags, merged with the workflow's static `@Workflow({ tags })` onto the run. */
|
|
2268
2302
|
tags?: string[] | undefined;
|
|
@@ -2596,6 +2630,12 @@ declare class WorkflowEngine {
|
|
|
2596
2630
|
/** Capabilities a live worker must advertise to run this workflow's turns (handshake §7.5).
|
|
2597
2631
|
* Only meaningful with `group`/`executor` (a remote/group-served workflow). Absent = runs anywhere. */
|
|
2598
2632
|
requires?: string[] | undefined;
|
|
2633
|
+
/** The package that DECLARED this workflow, stamped onto every run started from it (see
|
|
2634
|
+
* {@link WorkflowRun.origin}). Supplied by the registering integration — `@dudousxd/nestjs-durable`
|
|
2635
|
+
* derives it from the `@Workflow` class's declaring file — never by whoever calls `start`. Omit
|
|
2636
|
+
* when it cannot be derived with confidence: absent means UNKNOWN, and an absent origin is far
|
|
2637
|
+
* cheaper to live with than a wrong one. */
|
|
2638
|
+
origin?: string | undefined;
|
|
2599
2639
|
}): void;
|
|
2600
2640
|
/**
|
|
2601
2641
|
* The retained in-process body for `name@version`, for an IN-APP worker that consumes this engine's
|
|
@@ -3137,8 +3177,22 @@ declare class WorkflowEngine {
|
|
|
3137
3177
|
* cancel flag stays too, re-derived from the status on any later re-drive regardless.
|
|
3138
3178
|
*/
|
|
3139
3179
|
private compensateAndCancel;
|
|
3140
|
-
/**
|
|
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
|
+
*/
|
|
3141
3194
|
private runExecution;
|
|
3195
|
+
private runExecutionTurn;
|
|
3142
3196
|
/**
|
|
3143
3197
|
* Undo every registered saga compensation in strict reverse order — the shared unwind both the
|
|
3144
3198
|
* run-failure path (`runExecution`'s catch) and the compensating-cancel path
|
|
@@ -3630,6 +3684,70 @@ type RoutingResolution = RoutableResolution | BlockedResolution;
|
|
|
3630
3684
|
*/
|
|
3631
3685
|
declare function resolveRouting(handler: CapabilityRequirement, workers: readonly (RawWorkerDescriptor | WorkerDescriptor)[]): RoutingResolution;
|
|
3632
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
|
+
|
|
3633
3751
|
/** Canonical step id — the stable identity of a step within a run, used for dedupe and
|
|
3634
3752
|
* correlation. The format is part of the cross-language wire contract (Python builds the same). */
|
|
3635
3753
|
declare function stepId(runId: string, seq: number): string;
|
|
@@ -4305,4 +4423,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
|
|
|
4305
4423
|
onControl(handler: (msg: ControlMessage) => void): void;
|
|
4306
4424
|
}
|
|
4307
4425
|
|
|
4308
|
-
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",
|
|
@@ -2558,6 +2616,7 @@ var WorkflowEngine = class {
|
|
|
2558
2616
|
onEvent: opts?.onEvent,
|
|
2559
2617
|
eventBatch: opts?.eventBatch,
|
|
2560
2618
|
requires: opts?.requires,
|
|
2619
|
+
origin: opts?.origin,
|
|
2561
2620
|
// A real, retained in-process body — so `workflowBody` can hand it to an in-app worker, and so
|
|
2562
2621
|
// it is NOT confused with the throwing stub `registerRemote` installs for a body-less remote.
|
|
2563
2622
|
hasBody: true
|
|
@@ -2784,6 +2843,11 @@ var WorkflowEngine = class {
|
|
|
2784
2843
|
workflowVersion: registered.version,
|
|
2785
2844
|
status: "pending",
|
|
2786
2845
|
namespace: opts?.namespace ?? this.namespace,
|
|
2846
|
+
// DERIVED from the registration, exactly like `namespace` is derived from this engine — there is
|
|
2847
|
+
// deliberately no `opts.origin`, so a caller cannot label its run as another package's work.
|
|
2848
|
+
// `undefined` when the registration carried none (remote/convention/synthesized child, or a
|
|
2849
|
+
// registrar that could not resolve the declaring package): unknown, not "the app".
|
|
2850
|
+
origin: registered.origin,
|
|
2787
2851
|
input,
|
|
2788
2852
|
tags,
|
|
2789
2853
|
searchAttributes: opts?.searchAttributes,
|
|
@@ -4518,8 +4582,31 @@ var WorkflowEngine = class {
|
|
|
4518
4582
|
error: error2
|
|
4519
4583
|
};
|
|
4520
4584
|
}
|
|
4521
|
-
/**
|
|
4522
|
-
|
|
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) {
|
|
4523
4610
|
if (run.status === "cancelling") this.cancelRequested.add(run.id);
|
|
4524
4611
|
if (run.status === "pending") {
|
|
4525
4612
|
await this.store.updateRun(run.id, {
|
|
@@ -6129,6 +6216,7 @@ var InMemoryStateStore = class {
|
|
|
6129
6216
|
if (query.statuses) runs = runs.filter((r) => query.statuses?.includes(r.status));
|
|
6130
6217
|
if (query.tag) runs = runs.filter((r) => r.tags?.includes(query.tag));
|
|
6131
6218
|
if (query.namespace !== void 0) runs = runs.filter((r) => r.namespace === query.namespace);
|
|
6219
|
+
if (query.origin !== void 0) runs = runs.filter((r) => r.origin === query.origin);
|
|
6132
6220
|
if (query.attributes?.length) {
|
|
6133
6221
|
let candidates = null;
|
|
6134
6222
|
for (const f of query.attributes) {
|
|
@@ -6277,6 +6365,7 @@ export {
|
|
|
6277
6365
|
canRoute,
|
|
6278
6366
|
capableWorkers,
|
|
6279
6367
|
classifyWaiterToken,
|
|
6368
|
+
clearDurableExecutionWrappers,
|
|
6280
6369
|
collectMetrics,
|
|
6281
6370
|
controlPlaneDescriptor,
|
|
6282
6371
|
createStepLogger,
|
|
@@ -6290,6 +6379,7 @@ export {
|
|
|
6290
6379
|
eventNameOf,
|
|
6291
6380
|
eventPrefix,
|
|
6292
6381
|
eventToken,
|
|
6382
|
+
hasDurableExecutionWrappers,
|
|
6293
6383
|
heartbeatStatus,
|
|
6294
6384
|
indexWaitersByRun,
|
|
6295
6385
|
info,
|
|
@@ -6309,6 +6399,7 @@ export {
|
|
|
6309
6399
|
requiredCapabilities,
|
|
6310
6400
|
resolveRouting,
|
|
6311
6401
|
resolveRunWaiting,
|
|
6402
|
+
runDurableExecution,
|
|
6312
6403
|
runInStepLogger,
|
|
6313
6404
|
runInWorkflowCtx,
|
|
6314
6405
|
runSchedules,
|
|
@@ -6323,6 +6414,7 @@ export {
|
|
|
6323
6414
|
subEvent,
|
|
6324
6415
|
subProcess,
|
|
6325
6416
|
tenantGroup,
|
|
6417
|
+
useDurableExecution,
|
|
6326
6418
|
warn,
|
|
6327
6419
|
workflowName
|
|
6328
6420
|
};
|