@dudousxd/nestjs-durable-core 0.59.0 → 0.61.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.d.cts CHANGED
@@ -2060,6 +2060,66 @@ declare function runInWorkflowCtx<T>(ctx: WorkflowCtx, fn: () => T): T;
2060
2060
  */
2061
2061
  declare function currentWorkflowCtx(): WorkflowCtx | undefined;
2062
2062
 
2063
+ /**
2064
+ * Run `fn` with `logger` as the ambient step logger. Engine-internal: wraps every execution of a
2065
+ * step body, binding the SAME logger instance the body receives as its second argument — never a
2066
+ * second one, so an event emitted ambiently and one emitted through the argument land in the same
2067
+ * `StepEvent[]` and are checkpointed together.
2068
+ *
2069
+ * Because it is an `AsyncLocalStorage`, concurrent step invocations (the worker runs steps under
2070
+ * adaptive concurrency) each see their own logger — they never leak into one another.
2071
+ */
2072
+ declare function runInStepLogger<T>(logger: StepLogger, fn: () => T): T;
2073
+ /**
2074
+ * The {@link StepLogger} of the step body currently executing on this async path — or `undefined`
2075
+ * outside one. Reading it is the escape hatch for code that cannot take a logger parameter:
2076
+ *
2077
+ * ```ts
2078
+ * currentStep()?.subEvent({ id, name: 'insert', phase: `${rows} rows` });
2079
+ * ```
2080
+ */
2081
+ declare function currentStep(): StepLogger | undefined;
2082
+ /**
2083
+ * Record a log line on the current step, taking the level as a value. No-op outside a step. The
2084
+ * literal twin of the Python SDK's module-level `log(level, message, data)` — keep reaching for it
2085
+ * when the level is computed (mapping a foreign log level, re-emitting a captured record); for a
2086
+ * level known at the call site the per-level shortcuts below read better.
2087
+ *
2088
+ * The no-op contract is what lets a generic utility be instrumented without an `if` at the call
2089
+ * site, and keeps it usable in a unit test with no durable run around it.
2090
+ */
2091
+ declare function log(level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: unknown): void;
2092
+ /** Record a `debug` line on the current step. No-op outside a step. */
2093
+ declare function debug(message: string, data?: unknown): void;
2094
+ /** Record an `info` line on the current step. No-op outside a step. */
2095
+ declare function info(message: string, data?: unknown): void;
2096
+ /** Record a `warn` line on the current step. No-op outside a step. */
2097
+ declare function warn(message: string, data?: unknown): void;
2098
+ /** Record an `error` line on the current step. No-op outside a step — note this only RECORDS a line;
2099
+ * it never fails the step (that is what throwing from the body does). */
2100
+ declare function error(message: string, data?: unknown): void;
2101
+ /** Record a sub-step / sub-process outcome on the current step. No-op outside a step. */
2102
+ declare function sub(name: string, status: 'ok' | 'failed' | 'skipped', message?: string, data?: unknown): void;
2103
+ /** Record a sub-process event (phase or terminal outcome) on the current step. No-op outside a step. */
2104
+ declare function subEvent(e: {
2105
+ id: string;
2106
+ name: string;
2107
+ group?: string | undefined;
2108
+ phase?: string | undefined;
2109
+ status?: 'ok' | 'failed' | 'skipped' | undefined;
2110
+ message?: string | undefined;
2111
+ data?: unknown;
2112
+ }): void;
2113
+ /**
2114
+ * Run `body` as a timed sub-process of the current step (see {@link StepLogger.subProcess}).
2115
+ * Outside a step the body still RUNS — and still gets a handle — but nothing is emitted; only the
2116
+ * observability disappears, never the work. Mirrors the Python SDK's `sub_process`.
2117
+ */
2118
+ declare function subProcess<T>(name: string, body: (sp: SubProcessHandle) => Promise<T> | T, opts?: {
2119
+ group?: string;
2120
+ id?: string;
2121
+ }): Promise<T>;
2122
+
2063
2123
  /**
2064
2124
  * Cross-package, cross-runtime marker for engine CONTROL-FLOW signals — {@link WorkflowSuspended}
2065
2125
  * and {@link ContinueAsNew} (this package), plus the thin worker's {@link
@@ -2708,6 +2768,13 @@ declare class WorkflowEngine {
2708
2768
  * replay from their checkpoints, so only the work that had not finished runs again.
2709
2769
  */
2710
2770
  recoverIncomplete(nowMs?: number): Promise<RunResult[]>;
2771
+ /**
2772
+ * The remote step this run dispatched and is still awaiting a result for, if any — the signature
2773
+ * that tells {@link recoverIncomplete} "this run's work is ON THE TRANSPORT, not in a crashed
2774
+ * process". A `pending` remote checkpoint is written BEFORE the dispatch and settled by the
2775
+ * worker's result, so its presence is the durable marker of an in-flight dispatched step.
2776
+ */
2777
+ private inFlightRemoteStep;
2711
2778
  /**
2712
2779
  * Per-recovery bookkeeping (called once the lease is held): count the attempt, or — past
2713
2780
  * `maxRecoveryAttempts` — move a poison pill to the `dead` dead-letter state. Returns a terminal
@@ -2776,9 +2843,11 @@ declare class WorkflowEngine {
2776
2843
  * Explicitly re-dispatch every remote step of `runId` stuck `pending` — the OPERATOR escape hatch for
2777
2844
  * a run whose dispatched step job was LOST (worker crashed with no result, or a transport that dropped
2778
2845
  * the job). No automatic recovery re-drives these: a reconcile re-drive re-suspends a still-pending
2779
- * step by design (unless `remoteRedispatchMs` is set), `recoverIncomplete` only reclaims LEASED runs,
2780
- * and `requeue` just replays back to the pending guard. This re-enqueues the same `stepId` so the
2781
- * (idempotent) step re-runs and its result resumes the run. Safe to call on a healthy run — it re-runs
2846
+ * step by design (unless `remoteRedispatchMs` is set), `recoverIncomplete` explicitly SKIPS a run with
2847
+ * an in-flight `pending` remote step (it re-asserts the durably-suspended invariant instead of counting
2848
+ * a recovery attempt — see there), and `requeue` just replays back to the pending guard. This
2849
+ * re-enqueues the same `stepId` so the (idempotent) step re-runs and its result resumes the run.
2850
+ * Safe to call on a healthy run — it re-runs
2782
2851
  * only in-flight `pending` remote steps, which are idempotent by the durable contract. Returns the
2783
2852
  * run's current status (with the count re-dispatched), or null if the run is unknown.
2784
2853
  */
@@ -3645,15 +3714,21 @@ type WireDates<T> = {
3645
3714
  * a `ProxyRunGateway` that round-trips over the transport. Deliberately smaller than the full dashboard
3646
3715
  * (no metrics/bulk/update/signal) — those stay control-plane-only. `workerHealth` IS on the port: the
3647
3716
  * operator answers it scoped to the requester's own groups, so a tenant's Workers panel works too.
3717
+ *
3718
+ * Declared as an **abstract class** rather than an interface so it doubles as its own NestJS DI token
3719
+ * (the idiomatic inject-by-type pattern): providers bind `{ provide: RunGateway, useClass/useFactory }`
3720
+ * and consumers inject `constructor(private readonly gateway: RunGateway)` with no string/symbol token.
3721
+ * `StoreRunGateway`/`ProxyRunGateway` `implements RunGateway`; abstract methods carry no body, so the
3722
+ * emitted runtime class is an empty, non-instantiable shell used only as the token.
3648
3723
  */
3649
- interface RunGateway {
3724
+ declare abstract class RunGateway {
3650
3725
  /** This deployment's durable role (control plane vs tenant) — synchronous local metadata. */
3651
- topology(): DurableTopology;
3652
- getRunDetail(runId: string): Promise<RunDetail | null>;
3726
+ abstract topology(): DurableTopology;
3727
+ abstract getRunDetail(runId: string): Promise<RunDetail | null>;
3653
3728
  /** List runs, each optionally carrying a {@link RunWaiting} descriptor (what a suspended run is
3654
3729
  * parked on). The store-backed gateway resolves `waiting`; a proxy relays whatever the control
3655
3730
  * plane sent. */
3656
- listRuns(query: RunQuery): Promise<RunListItem[]>;
3731
+ abstract listRuns(query: RunQuery): Promise<RunListItem[]>;
3657
3732
  /**
3658
3733
  * Bulk-resolve {@link RunWaiting} for an arbitrary set of run ids — for a consumer with its OWN
3659
3734
  * filtered/paginated run listing (so it isn't just `listRuns` under another name) that needs to know
@@ -3664,26 +3739,26 @@ interface RunGateway {
3664
3739
  * parked on something non-event (a bare `ctx.sleep`, an in-flight step) are simply absent, same as a
3665
3740
  * `listRuns` row with no `waiting`.
3666
3741
  */
3667
- waitingFor(runIds: string[]): Promise<Record<string, RunWaiting>>;
3742
+ abstract waitingFor(runIds: string[]): Promise<Record<string, RunWaiting>>;
3668
3743
  /** Per-group worker health (queue backlog + live worker heartbeats). On the control plane this is
3669
3744
  * every group; over a tenant proxy the operator scopes it to the tenant's own groups. */
3670
- workerHealth(): Promise<GroupHealth[]>;
3671
- cancel(runId: string, opts?: {
3745
+ abstract workerHealth(): Promise<GroupHealth[]>;
3746
+ abstract cancel(runId: string, opts?: {
3672
3747
  compensate?: boolean;
3673
3748
  }): Promise<RunResult | null>;
3674
- retry(runId: string): Promise<RunResult | null>;
3675
- continue(runId: string): Promise<RunResult | null>;
3749
+ abstract retry(runId: string): Promise<RunResult | null>;
3750
+ abstract continue(runId: string): Promise<RunResult | null>;
3676
3751
  /** Re-dispatch every remote step of a run stuck `pending` — the operator recovery for a LOST step
3677
3752
  * dispatch (crashed worker / dropped job) that no automatic path re-drives. Returns the run's status
3678
3753
  * plus how many steps were re-dispatched, or null if the run is unknown. */
3679
- redispatchPending(runId: string): Promise<(RunResult & {
3754
+ abstract redispatchPending(runId: string): Promise<(RunResult & {
3680
3755
  redispatched: number;
3681
3756
  }) | null>;
3682
- retryWithInput(runId: string, input: unknown): Promise<{
3757
+ abstract retryWithInput(runId: string, input: unknown): Promise<{
3683
3758
  runId: string;
3684
3759
  } | null>;
3685
3760
  /** Live lifecycle events for one run; returns an unsubscribe fn. Framework-agnostic (no rxjs). */
3686
- subscribe(runId: string, onEvent: (event: EngineEvent) => void): () => void;
3761
+ abstract subscribe(runId: string, onEvent: (event: EngineEvent) => void): () => void;
3687
3762
  }
3688
3763
 
3689
3764
  /**
@@ -4217,4 +4292,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
4217
4292
  onControl(handler: (msg: ControlMessage) => void): void;
4218
4293
  }
4219
4294
 
4220
- 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, 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 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, currentWorkflowCtx, descriptorHash, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, heartbeatStatus, indexWaitersByRun, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, matchesAttributes, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, parseDuration, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, tenantGroup, workflowName };
4295
+ 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 };
package/dist/index.d.ts CHANGED
@@ -2060,6 +2060,66 @@ declare function runInWorkflowCtx<T>(ctx: WorkflowCtx, fn: () => T): T;
2060
2060
  */
2061
2061
  declare function currentWorkflowCtx(): WorkflowCtx | undefined;
2062
2062
 
2063
+ /**
2064
+ * Run `fn` with `logger` as the ambient step logger. Engine-internal: wraps every execution of a
2065
+ * step body, binding the SAME logger instance the body receives as its second argument — never a
2066
+ * second one, so an event emitted ambiently and one emitted through the argument land in the same
2067
+ * `StepEvent[]` and are checkpointed together.
2068
+ *
2069
+ * Because it is an `AsyncLocalStorage`, concurrent step invocations (the worker runs steps under
2070
+ * adaptive concurrency) each see their own logger — they never leak into one another.
2071
+ */
2072
+ declare function runInStepLogger<T>(logger: StepLogger, fn: () => T): T;
2073
+ /**
2074
+ * The {@link StepLogger} of the step body currently executing on this async path — or `undefined`
2075
+ * outside one. Reading it is the escape hatch for code that cannot take a logger parameter:
2076
+ *
2077
+ * ```ts
2078
+ * currentStep()?.subEvent({ id, name: 'insert', phase: `${rows} rows` });
2079
+ * ```
2080
+ */
2081
+ declare function currentStep(): StepLogger | undefined;
2082
+ /**
2083
+ * Record a log line on the current step, taking the level as a value. No-op outside a step. The
2084
+ * literal twin of the Python SDK's module-level `log(level, message, data)` — keep reaching for it
2085
+ * when the level is computed (mapping a foreign log level, re-emitting a captured record); for a
2086
+ * level known at the call site the per-level shortcuts below read better.
2087
+ *
2088
+ * The no-op contract is what lets a generic utility be instrumented without an `if` at the call
2089
+ * site, and keeps it usable in a unit test with no durable run around it.
2090
+ */
2091
+ declare function log(level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: unknown): void;
2092
+ /** Record a `debug` line on the current step. No-op outside a step. */
2093
+ declare function debug(message: string, data?: unknown): void;
2094
+ /** Record an `info` line on the current step. No-op outside a step. */
2095
+ declare function info(message: string, data?: unknown): void;
2096
+ /** Record a `warn` line on the current step. No-op outside a step. */
2097
+ declare function warn(message: string, data?: unknown): void;
2098
+ /** Record an `error` line on the current step. No-op outside a step — note this only RECORDS a line;
2099
+ * it never fails the step (that is what throwing from the body does). */
2100
+ declare function error(message: string, data?: unknown): void;
2101
+ /** Record a sub-step / sub-process outcome on the current step. No-op outside a step. */
2102
+ declare function sub(name: string, status: 'ok' | 'failed' | 'skipped', message?: string, data?: unknown): void;
2103
+ /** Record a sub-process event (phase or terminal outcome) on the current step. No-op outside a step. */
2104
+ declare function subEvent(e: {
2105
+ id: string;
2106
+ name: string;
2107
+ group?: string | undefined;
2108
+ phase?: string | undefined;
2109
+ status?: 'ok' | 'failed' | 'skipped' | undefined;
2110
+ message?: string | undefined;
2111
+ data?: unknown;
2112
+ }): void;
2113
+ /**
2114
+ * Run `body` as a timed sub-process of the current step (see {@link StepLogger.subProcess}).
2115
+ * Outside a step the body still RUNS — and still gets a handle — but nothing is emitted; only the
2116
+ * observability disappears, never the work. Mirrors the Python SDK's `sub_process`.
2117
+ */
2118
+ declare function subProcess<T>(name: string, body: (sp: SubProcessHandle) => Promise<T> | T, opts?: {
2119
+ group?: string;
2120
+ id?: string;
2121
+ }): Promise<T>;
2122
+
2063
2123
  /**
2064
2124
  * Cross-package, cross-runtime marker for engine CONTROL-FLOW signals — {@link WorkflowSuspended}
2065
2125
  * and {@link ContinueAsNew} (this package), plus the thin worker's {@link
@@ -2708,6 +2768,13 @@ declare class WorkflowEngine {
2708
2768
  * replay from their checkpoints, so only the work that had not finished runs again.
2709
2769
  */
2710
2770
  recoverIncomplete(nowMs?: number): Promise<RunResult[]>;
2771
+ /**
2772
+ * The remote step this run dispatched and is still awaiting a result for, if any — the signature
2773
+ * that tells {@link recoverIncomplete} "this run's work is ON THE TRANSPORT, not in a crashed
2774
+ * process". A `pending` remote checkpoint is written BEFORE the dispatch and settled by the
2775
+ * worker's result, so its presence is the durable marker of an in-flight dispatched step.
2776
+ */
2777
+ private inFlightRemoteStep;
2711
2778
  /**
2712
2779
  * Per-recovery bookkeeping (called once the lease is held): count the attempt, or — past
2713
2780
  * `maxRecoveryAttempts` — move a poison pill to the `dead` dead-letter state. Returns a terminal
@@ -2776,9 +2843,11 @@ declare class WorkflowEngine {
2776
2843
  * Explicitly re-dispatch every remote step of `runId` stuck `pending` — the OPERATOR escape hatch for
2777
2844
  * a run whose dispatched step job was LOST (worker crashed with no result, or a transport that dropped
2778
2845
  * the job). No automatic recovery re-drives these: a reconcile re-drive re-suspends a still-pending
2779
- * step by design (unless `remoteRedispatchMs` is set), `recoverIncomplete` only reclaims LEASED runs,
2780
- * and `requeue` just replays back to the pending guard. This re-enqueues the same `stepId` so the
2781
- * (idempotent) step re-runs and its result resumes the run. Safe to call on a healthy run — it re-runs
2846
+ * step by design (unless `remoteRedispatchMs` is set), `recoverIncomplete` explicitly SKIPS a run with
2847
+ * an in-flight `pending` remote step (it re-asserts the durably-suspended invariant instead of counting
2848
+ * a recovery attempt — see there), and `requeue` just replays back to the pending guard. This
2849
+ * re-enqueues the same `stepId` so the (idempotent) step re-runs and its result resumes the run.
2850
+ * Safe to call on a healthy run — it re-runs
2782
2851
  * only in-flight `pending` remote steps, which are idempotent by the durable contract. Returns the
2783
2852
  * run's current status (with the count re-dispatched), or null if the run is unknown.
2784
2853
  */
@@ -3645,15 +3714,21 @@ type WireDates<T> = {
3645
3714
  * a `ProxyRunGateway` that round-trips over the transport. Deliberately smaller than the full dashboard
3646
3715
  * (no metrics/bulk/update/signal) — those stay control-plane-only. `workerHealth` IS on the port: the
3647
3716
  * operator answers it scoped to the requester's own groups, so a tenant's Workers panel works too.
3717
+ *
3718
+ * Declared as an **abstract class** rather than an interface so it doubles as its own NestJS DI token
3719
+ * (the idiomatic inject-by-type pattern): providers bind `{ provide: RunGateway, useClass/useFactory }`
3720
+ * and consumers inject `constructor(private readonly gateway: RunGateway)` with no string/symbol token.
3721
+ * `StoreRunGateway`/`ProxyRunGateway` `implements RunGateway`; abstract methods carry no body, so the
3722
+ * emitted runtime class is an empty, non-instantiable shell used only as the token.
3648
3723
  */
3649
- interface RunGateway {
3724
+ declare abstract class RunGateway {
3650
3725
  /** This deployment's durable role (control plane vs tenant) — synchronous local metadata. */
3651
- topology(): DurableTopology;
3652
- getRunDetail(runId: string): Promise<RunDetail | null>;
3726
+ abstract topology(): DurableTopology;
3727
+ abstract getRunDetail(runId: string): Promise<RunDetail | null>;
3653
3728
  /** List runs, each optionally carrying a {@link RunWaiting} descriptor (what a suspended run is
3654
3729
  * parked on). The store-backed gateway resolves `waiting`; a proxy relays whatever the control
3655
3730
  * plane sent. */
3656
- listRuns(query: RunQuery): Promise<RunListItem[]>;
3731
+ abstract listRuns(query: RunQuery): Promise<RunListItem[]>;
3657
3732
  /**
3658
3733
  * Bulk-resolve {@link RunWaiting} for an arbitrary set of run ids — for a consumer with its OWN
3659
3734
  * filtered/paginated run listing (so it isn't just `listRuns` under another name) that needs to know
@@ -3664,26 +3739,26 @@ interface RunGateway {
3664
3739
  * parked on something non-event (a bare `ctx.sleep`, an in-flight step) are simply absent, same as a
3665
3740
  * `listRuns` row with no `waiting`.
3666
3741
  */
3667
- waitingFor(runIds: string[]): Promise<Record<string, RunWaiting>>;
3742
+ abstract waitingFor(runIds: string[]): Promise<Record<string, RunWaiting>>;
3668
3743
  /** Per-group worker health (queue backlog + live worker heartbeats). On the control plane this is
3669
3744
  * every group; over a tenant proxy the operator scopes it to the tenant's own groups. */
3670
- workerHealth(): Promise<GroupHealth[]>;
3671
- cancel(runId: string, opts?: {
3745
+ abstract workerHealth(): Promise<GroupHealth[]>;
3746
+ abstract cancel(runId: string, opts?: {
3672
3747
  compensate?: boolean;
3673
3748
  }): Promise<RunResult | null>;
3674
- retry(runId: string): Promise<RunResult | null>;
3675
- continue(runId: string): Promise<RunResult | null>;
3749
+ abstract retry(runId: string): Promise<RunResult | null>;
3750
+ abstract continue(runId: string): Promise<RunResult | null>;
3676
3751
  /** Re-dispatch every remote step of a run stuck `pending` — the operator recovery for a LOST step
3677
3752
  * dispatch (crashed worker / dropped job) that no automatic path re-drives. Returns the run's status
3678
3753
  * plus how many steps were re-dispatched, or null if the run is unknown. */
3679
- redispatchPending(runId: string): Promise<(RunResult & {
3754
+ abstract redispatchPending(runId: string): Promise<(RunResult & {
3680
3755
  redispatched: number;
3681
3756
  }) | null>;
3682
- retryWithInput(runId: string, input: unknown): Promise<{
3757
+ abstract retryWithInput(runId: string, input: unknown): Promise<{
3683
3758
  runId: string;
3684
3759
  } | null>;
3685
3760
  /** Live lifecycle events for one run; returns an unsubscribe fn. Framework-agnostic (no rxjs). */
3686
- subscribe(runId: string, onEvent: (event: EngineEvent) => void): () => void;
3761
+ abstract subscribe(runId: string, onEvent: (event: EngineEvent) => void): () => void;
3687
3762
  }
3688
3763
 
3689
3764
  /**
@@ -4217,4 +4292,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
4217
4292
  onControl(handler: (msg: ControlMessage) => void): void;
4218
4293
  }
4219
4294
 
4220
- 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, 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 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, currentWorkflowCtx, descriptorHash, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, heartbeatStatus, indexWaitersByRun, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, matchesAttributes, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, parseDuration, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runInWorkflowCtx, runSchedules, runStepHandler, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, tenantGroup, workflowName };
4295
+ 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 };