@dudousxd/nestjs-durable-core 0.69.0 → 0.70.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
@@ -1260,6 +1260,16 @@ interface RunValueFacetRow {
1260
1260
  value: string | null;
1261
1261
  count: number;
1262
1262
  }
1263
+ /**
1264
+ * The order {@link StateStore.runValueFacets} returns rows in, and the reason a caller can page
1265
+ * them: most runs first, ties broken alphabetically, the absent bucket (`null`) last — and tags the
1266
+ * engine mints one of per key after everything else, since they otherwise crowd out every tag a
1267
+ * human wrote (see `ENGINE_MINTED_TAG_PREFIXES`).
1268
+ *
1269
+ * Fixed, not incidental: an unordered listing cannot be paged, because page two would be taken over
1270
+ * a different arrangement of the same rows and would both repeat and skip.
1271
+ */
1272
+ type RunValueFacetOrder = 'engine-tags-last, count desc, value asc, null last';
1263
1273
  /**
1264
1274
  * How much of the store {@link StateStore.runValueFacets} may read to answer.
1265
1275
  *
@@ -1267,15 +1277,35 @@ interface RunValueFacetRow {
1267
1277
  * unbounded in principle — a run tagged `singleton:<key>` mints a new tag per key — so a picker asks
1268
1278
  * for the top slice rather than the whole domain, and keeps free text for everything else.
1269
1279
  *
1270
- * `scan` bounds the RUNS READ, and applies to the axes whose values are not a column of the run row
1271
- * being counted — `tag` (inside a JSON array column) and the two attribute axes (a side table). Those
1272
- * report counts over the newest `scan` matching runs rather than over all of them: a bounded,
1273
- * deliberately approximate answer, where the alternative is a full scan on every keystroke. The
1274
- * column axes (`workflow`, `status`, `origin`, `namespace`) are exact and ignore `scan`.
1280
+ * `scan` bounds the RUNS READ, for a store that cannot group an axis in the database and has to
1281
+ * count it in memory instead. Those axes report over the newest `scan` matching runs rather than
1282
+ * over all of them — a bounded, deliberately approximate answer, where the alternative is a full
1283
+ * scan on every keystroke.
1284
+ *
1285
+ * Which axes those are is a property of the ADAPTER, not of the axis: the column axes are a `GROUP
1286
+ * BY` everywhere, and an adapter that can expand a JSON array and join its attribute side table (the
1287
+ * MikroORM one does) answers `tag` and the attribute axes exactly too, ignoring `scan` entirely.
1275
1288
  */
1276
1289
  interface RunValueFacetOptions {
1277
1290
  limit?: number | undefined;
1278
1291
  scan?: number | undefined;
1292
+ /**
1293
+ * How many rows to skip, for a picker that pages as it scrolls. Meaningful only because the
1294
+ * ordering is fixed (see {@link RunValueFacetRow}), so page two continues page one instead of
1295
+ * re-shuffling it.
1296
+ *
1297
+ * On an axis answered from a bounded scan rather than a `GROUP BY` (see {@link scan}), paging is
1298
+ * over that window: values outside it were never candidates on page one either.
1299
+ */
1300
+ offset?: number | undefined;
1301
+ /**
1302
+ * Narrow to values CONTAINING this text, case-insensitively — what a picker's search box sends.
1303
+ *
1304
+ * Server-side on purpose. A picker that filters an already-fetched page can only search what it
1305
+ * happened to receive, so a rare value is unfindable precisely when searching is the only way to
1306
+ * reach it: the top slice it was cut from is the reason the operator is typing.
1307
+ */
1308
+ search?: string | undefined;
1279
1309
  }
1280
1310
  /** The transaction handle `StateStore.transaction` hands to its work callback. */
1281
1311
  interface StoreTransaction {
@@ -3692,6 +3722,15 @@ declare class WorkflowEngine {
3692
3722
  /**
3693
3723
  * Resume each run only if this instance can acquire its recovery lease — so when several
3694
3724
  * replicas recover or poll at once, each run is picked up by exactly one of them.
3725
+ *
3726
+ * A run this instance cannot resume is SKIPPED, not allowed to abort the batch. The canonical
3727
+ * case is skew protection: mid-rolling-deploy a pod leases a run whose workflow it does not have
3728
+ * and `resume` throws by design — but the rest of the batch is runs it can drive perfectly well,
3729
+ * and every caller here is a recovery sweep. Letting the first such run end the loop means one
3730
+ * row stops recovery for the whole deployment, and (since the callers are pollers) sends the
3731
+ * rejection into a lifecycle hook. Skipping leaves the run locked only until its lease expires,
3732
+ * for a pod that does have the workflow — which is exactly what the skew-protection error asks
3733
+ * for. Same posture as `publishEvent`'s per-subscriber isolation.
3695
3734
  */
3696
3735
  private resumeLeased;
3697
3736
  /**
@@ -4522,20 +4561,20 @@ declare function isEngineMintedTag(value: string | null): boolean;
4522
4561
  * Is this axis a plain column on the runs table, and so countable with a `GROUP BY` over the whole
4523
4562
  * matching set?
4524
4563
  *
4525
- * The other three are not, in the same way for the same reason — the value isn't in a column of the
4526
- * row being counted. A run's tags live inside ONE json array column that no `GROUP BY` portable
4527
- * across sqlite/MySQL/Postgres reaches into, and its search attributes live in a side table whose
4528
- * join back to the filtered run set differs per adapter. Those axes are counted in-process over a
4529
- * bounded scan instead ({@link runValueFacetsFromRuns}), so their counts describe that window rather
4530
- * than the whole store — which is why {@link RunValueFacetOptions.scan} exists.
4564
+ * The other three are not: the value isn't in a column of the row being counted. A run's tags live
4565
+ * inside ONE json array column, and its search attributes in a side table. Neither has a form that
4566
+ * is the same across sqlite/MySQL/Postgres — each engine expands a JSON array its own way — so an
4567
+ * adapter either writes that dialect SQL (the MikroORM one does, and answers those axes exactly) or
4568
+ * counts them in-process over a bounded scan ({@link runValueFacetsFromRuns}), where the counts
4569
+ * describe that window rather than the whole store. This function is what the second kind uses.
4531
4570
  */
4532
4571
  declare function axisIsRunColumn(axis: RunValueAxis): axis is {
4533
4572
  field: 'workflow' | 'status' | 'origin' | 'namespace';
4534
4573
  };
4535
4574
  /**
4536
- * Fold, order and bound raw `(value, count)` rows into the answer callers see: highest count first,
4537
- * ties broken alphabetically so a picker's order is stable between polls, the unattributed bucket
4538
- * (`null`) last, and no more than `limit` rows.
4575
+ * Fold, order, search and bound raw `(value, count)` rows into the answer callers see: highest count
4576
+ * first, ties broken alphabetically so a picker's order is stable between polls (and therefore
4577
+ * pageable), the unattributed bucket (`null`) last, and one `limit`-sized page from `offset`.
4539
4578
  *
4540
4579
  * Every store pipes its `GROUP BY` through this — the same role {@link mergeRunFacetRows} plays for
4541
4580
  * status/origin counts — so a picker lists the same values in the same order whichever adapter is
@@ -5233,4 +5272,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
5233
5272
  onControl(handler: (msg: ControlMessage) => void): void;
5234
5273
  }
5235
5274
 
5236
- export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AnnouncedWorkflow, type AnnouncementEvidence, type AttributeFilter, type AttributeOp, type AttributePredicateOperand, type AttributeValue, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DEFAULT_PARTITION, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type Disagreement, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, ENGINE_MINTED_TAG_PREFIXES, 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 HeartbeatSighting, 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 PartitionSighting, type PayloadCodec, type QueueConfig, QueueController, RUN_VALUE_FACET_LIMIT, RUN_VALUE_FACET_SCAN, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunFacetQuery, type RunFacetRow, RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunValueAxis, type RunValueFacetOptions, type RunValueFacetRow, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, type ScalarAttributeFilter, 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, VERSION_UNDECLARED_TAG, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, type WorkflowAnnouncement, WorkflowBlocked, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, type WorkflowDirectory, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRegistration, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, aggregateAnnouncements, announcementsOf, applyAttributeQuery, attributeColumnFor, attributeOperand, attributePredicateOperands, axisIsRunColumn, bindWorkflowClass, breakpointToken, buildWorkflowDirectory, canRoute, capableWorkers, classifyWaiterToken, clearDurableExecutionWrappers, collectMetrics, controlPlaneDescriptor, coveredTokens, createStepLogger, currentStep, currentWorkflowCtx, debug, describeWorker, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, facetOrigin, hasDurableExecutionWrappers, heartbeatStatus, indexWaitersByRun, info, isEngineMintedTag, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, parseDuration, partitionOfToken, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runDurableExecution, runInStepLogger, runInWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };
5275
+ export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AnnouncedWorkflow, type AnnouncementEvidence, type AttributeFilter, type AttributeOp, type AttributePredicateOperand, type AttributeValue, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DEFAULT_PARTITION, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type Disagreement, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, ENGINE_MINTED_TAG_PREFIXES, 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 HeartbeatSighting, 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 PartitionSighting, type PayloadCodec, type QueueConfig, QueueController, RUN_VALUE_FACET_LIMIT, RUN_VALUE_FACET_SCAN, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunFacetQuery, type RunFacetRow, RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunValueAxis, type RunValueFacetOptions, type RunValueFacetOrder, type RunValueFacetRow, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, type ScalarAttributeFilter, 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, VERSION_UNDECLARED_TAG, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, type WorkflowAnnouncement, WorkflowBlocked, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, type WorkflowDirectory, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRegistration, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, aggregateAnnouncements, announcementsOf, applyAttributeQuery, attributeColumnFor, attributeOperand, attributePredicateOperands, axisIsRunColumn, bindWorkflowClass, breakpointToken, buildWorkflowDirectory, canRoute, capableWorkers, classifyWaiterToken, clearDurableExecutionWrappers, collectMetrics, controlPlaneDescriptor, coveredTokens, createStepLogger, currentStep, currentWorkflowCtx, debug, describeWorker, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, facetOrigin, hasDurableExecutionWrappers, heartbeatStatus, indexWaitersByRun, info, isEngineMintedTag, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, parseDuration, partitionOfToken, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runDurableExecution, runInStepLogger, runInWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };
package/dist/index.d.ts CHANGED
@@ -1260,6 +1260,16 @@ interface RunValueFacetRow {
1260
1260
  value: string | null;
1261
1261
  count: number;
1262
1262
  }
1263
+ /**
1264
+ * The order {@link StateStore.runValueFacets} returns rows in, and the reason a caller can page
1265
+ * them: most runs first, ties broken alphabetically, the absent bucket (`null`) last — and tags the
1266
+ * engine mints one of per key after everything else, since they otherwise crowd out every tag a
1267
+ * human wrote (see `ENGINE_MINTED_TAG_PREFIXES`).
1268
+ *
1269
+ * Fixed, not incidental: an unordered listing cannot be paged, because page two would be taken over
1270
+ * a different arrangement of the same rows and would both repeat and skip.
1271
+ */
1272
+ type RunValueFacetOrder = 'engine-tags-last, count desc, value asc, null last';
1263
1273
  /**
1264
1274
  * How much of the store {@link StateStore.runValueFacets} may read to answer.
1265
1275
  *
@@ -1267,15 +1277,35 @@ interface RunValueFacetRow {
1267
1277
  * unbounded in principle — a run tagged `singleton:<key>` mints a new tag per key — so a picker asks
1268
1278
  * for the top slice rather than the whole domain, and keeps free text for everything else.
1269
1279
  *
1270
- * `scan` bounds the RUNS READ, and applies to the axes whose values are not a column of the run row
1271
- * being counted — `tag` (inside a JSON array column) and the two attribute axes (a side table). Those
1272
- * report counts over the newest `scan` matching runs rather than over all of them: a bounded,
1273
- * deliberately approximate answer, where the alternative is a full scan on every keystroke. The
1274
- * column axes (`workflow`, `status`, `origin`, `namespace`) are exact and ignore `scan`.
1280
+ * `scan` bounds the RUNS READ, for a store that cannot group an axis in the database and has to
1281
+ * count it in memory instead. Those axes report over the newest `scan` matching runs rather than
1282
+ * over all of them — a bounded, deliberately approximate answer, where the alternative is a full
1283
+ * scan on every keystroke.
1284
+ *
1285
+ * Which axes those are is a property of the ADAPTER, not of the axis: the column axes are a `GROUP
1286
+ * BY` everywhere, and an adapter that can expand a JSON array and join its attribute side table (the
1287
+ * MikroORM one does) answers `tag` and the attribute axes exactly too, ignoring `scan` entirely.
1275
1288
  */
1276
1289
  interface RunValueFacetOptions {
1277
1290
  limit?: number | undefined;
1278
1291
  scan?: number | undefined;
1292
+ /**
1293
+ * How many rows to skip, for a picker that pages as it scrolls. Meaningful only because the
1294
+ * ordering is fixed (see {@link RunValueFacetRow}), so page two continues page one instead of
1295
+ * re-shuffling it.
1296
+ *
1297
+ * On an axis answered from a bounded scan rather than a `GROUP BY` (see {@link scan}), paging is
1298
+ * over that window: values outside it were never candidates on page one either.
1299
+ */
1300
+ offset?: number | undefined;
1301
+ /**
1302
+ * Narrow to values CONTAINING this text, case-insensitively — what a picker's search box sends.
1303
+ *
1304
+ * Server-side on purpose. A picker that filters an already-fetched page can only search what it
1305
+ * happened to receive, so a rare value is unfindable precisely when searching is the only way to
1306
+ * reach it: the top slice it was cut from is the reason the operator is typing.
1307
+ */
1308
+ search?: string | undefined;
1279
1309
  }
1280
1310
  /** The transaction handle `StateStore.transaction` hands to its work callback. */
1281
1311
  interface StoreTransaction {
@@ -3692,6 +3722,15 @@ declare class WorkflowEngine {
3692
3722
  /**
3693
3723
  * Resume each run only if this instance can acquire its recovery lease — so when several
3694
3724
  * replicas recover or poll at once, each run is picked up by exactly one of them.
3725
+ *
3726
+ * A run this instance cannot resume is SKIPPED, not allowed to abort the batch. The canonical
3727
+ * case is skew protection: mid-rolling-deploy a pod leases a run whose workflow it does not have
3728
+ * and `resume` throws by design — but the rest of the batch is runs it can drive perfectly well,
3729
+ * and every caller here is a recovery sweep. Letting the first such run end the loop means one
3730
+ * row stops recovery for the whole deployment, and (since the callers are pollers) sends the
3731
+ * rejection into a lifecycle hook. Skipping leaves the run locked only until its lease expires,
3732
+ * for a pod that does have the workflow — which is exactly what the skew-protection error asks
3733
+ * for. Same posture as `publishEvent`'s per-subscriber isolation.
3695
3734
  */
3696
3735
  private resumeLeased;
3697
3736
  /**
@@ -4522,20 +4561,20 @@ declare function isEngineMintedTag(value: string | null): boolean;
4522
4561
  * Is this axis a plain column on the runs table, and so countable with a `GROUP BY` over the whole
4523
4562
  * matching set?
4524
4563
  *
4525
- * The other three are not, in the same way for the same reason — the value isn't in a column of the
4526
- * row being counted. A run's tags live inside ONE json array column that no `GROUP BY` portable
4527
- * across sqlite/MySQL/Postgres reaches into, and its search attributes live in a side table whose
4528
- * join back to the filtered run set differs per adapter. Those axes are counted in-process over a
4529
- * bounded scan instead ({@link runValueFacetsFromRuns}), so their counts describe that window rather
4530
- * than the whole store — which is why {@link RunValueFacetOptions.scan} exists.
4564
+ * The other three are not: the value isn't in a column of the row being counted. A run's tags live
4565
+ * inside ONE json array column, and its search attributes in a side table. Neither has a form that
4566
+ * is the same across sqlite/MySQL/Postgres — each engine expands a JSON array its own way — so an
4567
+ * adapter either writes that dialect SQL (the MikroORM one does, and answers those axes exactly) or
4568
+ * counts them in-process over a bounded scan ({@link runValueFacetsFromRuns}), where the counts
4569
+ * describe that window rather than the whole store. This function is what the second kind uses.
4531
4570
  */
4532
4571
  declare function axisIsRunColumn(axis: RunValueAxis): axis is {
4533
4572
  field: 'workflow' | 'status' | 'origin' | 'namespace';
4534
4573
  };
4535
4574
  /**
4536
- * Fold, order and bound raw `(value, count)` rows into the answer callers see: highest count first,
4537
- * ties broken alphabetically so a picker's order is stable between polls, the unattributed bucket
4538
- * (`null`) last, and no more than `limit` rows.
4575
+ * Fold, order, search and bound raw `(value, count)` rows into the answer callers see: highest count
4576
+ * first, ties broken alphabetically so a picker's order is stable between polls (and therefore
4577
+ * pageable), the unattributed bucket (`null`) last, and one `limit`-sized page from `offset`.
4539
4578
  *
4540
4579
  * Every store pipes its `GROUP BY` through this — the same role {@link mergeRunFacetRows} plays for
4541
4580
  * status/origin counts — so a picker lists the same values in the same order whichever adapter is
@@ -5233,4 +5272,4 @@ declare class InMemoryTransport implements Transport, ControlPlane {
5233
5272
  onControl(handler: (msg: ControlMessage) => void): void;
5234
5273
  }
5235
5274
 
5236
- export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AnnouncedWorkflow, type AnnouncementEvidence, type AttributeFilter, type AttributeOp, type AttributePredicateOperand, type AttributeValue, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DEFAULT_PARTITION, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type Disagreement, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, ENGINE_MINTED_TAG_PREFIXES, 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 HeartbeatSighting, 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 PartitionSighting, type PayloadCodec, type QueueConfig, QueueController, RUN_VALUE_FACET_LIMIT, RUN_VALUE_FACET_SCAN, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunFacetQuery, type RunFacetRow, RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunValueAxis, type RunValueFacetOptions, type RunValueFacetRow, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, type ScalarAttributeFilter, 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, VERSION_UNDECLARED_TAG, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, type WorkflowAnnouncement, WorkflowBlocked, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, type WorkflowDirectory, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRegistration, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, aggregateAnnouncements, announcementsOf, applyAttributeQuery, attributeColumnFor, attributeOperand, attributePredicateOperands, axisIsRunColumn, bindWorkflowClass, breakpointToken, buildWorkflowDirectory, canRoute, capableWorkers, classifyWaiterToken, clearDurableExecutionWrappers, collectMetrics, controlPlaneDescriptor, coveredTokens, createStepLogger, currentStep, currentWorkflowCtx, debug, describeWorker, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, facetOrigin, hasDurableExecutionWrappers, heartbeatStatus, indexWaitersByRun, info, isEngineMintedTag, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, parseDuration, partitionOfToken, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runDurableExecution, runInStepLogger, runInWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };
5275
+ export { type AccumulatorHost, type Admission, type AdmissionBackend, type AdmissionItem, type AnnouncedWorkflow, type AnnouncementEvidence, type AttributeFilter, type AttributeOp, type AttributePredicateOperand, type AttributeValue, type BackoffStrategy, type BlockedDispatch, type BlockedResolution, CONTROL_FLOW_SIGNAL, CURRENT_PROTOCOL_VERSION, type CapabilityRequirement, type ChildCallOptions, CodecStateStore, ContinueAsNew, type ControlMessage, type ControlPlane, DEFAULT_PARTITION, DURABLE_OPTIONS, DURABLE_OPTIONS_CANONICAL, DURABLE_STEP_CONFIG, DURABLE_STEP_NAME, type Disagreement, type DispatchDiagnostics, type DispatchPlan, type DurableExecution, type DurableExecutionWrapper, type DurableTopology, type DurableWebhook, DurableWorkflow, ENGINE_MINTED_TAG_PREFIXES, 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 HeartbeatSighting, 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 PartitionSighting, type PayloadCodec, type QueueConfig, QueueController, RUN_VALUE_FACET_LIMIT, RUN_VALUE_FACET_SCAN, type RawWorkerDescriptor, RemoteStepError, RemoteStepTimeout, type RemoteTask, RemoteWorkflowExecutor, RemoteWorkflowTimeout, type RetentionPolicy, type RoutableDispatch, type RoutableResolution, type RoutingResolution, type RunAttributeRow, type RunDetail, type RunDispatcher, type RunFacetQuery, type RunFacetRow, RunGateway, type RunListItem, type RunQuery, type RunReply, type RunReplyResult, type RunRequest, type RunRequestKind, type RunResult, type RunSchedulesOptions, type RunStatus, type RunValueAxis, type RunValueFacetOptions, type RunValueFacetOrder, type RunValueFacetRow, type RunWaiting, STATE_STORE, STATE_STORE_CANONICAL, type ScalarAttributeFilter, 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, VERSION_UNDECLARED_TAG, WORKFLOW_NAME_KEY, type WireDates, type WorkerAdjust, type WorkerConcurrencyStatus, type WorkerDescriptor, type WorkerHeartbeat, type WorkerLifecycle, type WorkerStatus, type WorkflowAnnouncement, WorkflowBlocked, type WorkflowClass, type WorkflowCommand, type WorkflowCtx, type WorkflowDecision, type WorkflowDirectory, WorkflowEngine, type WorkflowEngineDeps, type WorkflowExecutor, type WorkflowHandler, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRef, type WorkflowRegistration, type WorkflowRun, type WorkflowStartClient, type WorkflowStepEvent, WorkflowSuspended, type WorkflowTask, aggregateAnnouncements, announcementsOf, applyAttributeQuery, attributeColumnFor, attributeOperand, attributePredicateOperands, axisIsRunColumn, bindWorkflowClass, breakpointToken, buildWorkflowDirectory, canRoute, capableWorkers, classifyWaiterToken, clearDurableExecutionWrappers, collectMetrics, controlPlaneDescriptor, coveredTokens, createStepLogger, currentStep, currentWorkflowCtx, debug, describeWorker, descriptorHash, error, eventMatchOf, eventMatches, eventNameOf, eventPrefix, eventToken, facetOrigin, hasDurableExecutionWrappers, heartbeatStatus, indexWaitersByRun, info, isEngineMintedTag, isEventToken, isLegacyDescriptor, isWorkflowControlFlowSignal, log, matchesAttributes, mergeRunFacetRows, mergeRunValueFacetRows, missingCapabilities, negotiate, normalizeAttributeRows, normalizeDescriptor, observedAnnouncements, parseDuration, partitionOfToken, planDispatch, prevCronFireMs, readSearchAttributes, requiredCapabilities, resolveRouting, resolveRunWaiting, runDurableExecution, runInStepLogger, runInWorkflowCtx, runSchedules, runStepHandler, runValueFacetsFromRuns, sanitizeQueueToken, scheduledRunId, sqlComparator, stepConfigOf, stepId, stepNameOf, sub, subEvent, subProcess, tenantGroup, useDurableExecution, warn, workflowName };
package/dist/index.js CHANGED
@@ -3889,6 +3889,15 @@ var WorkflowEngine = class {
3889
3889
  /**
3890
3890
  * Resume each run only if this instance can acquire its recovery lease — so when several
3891
3891
  * replicas recover or poll at once, each run is picked up by exactly one of them.
3892
+ *
3893
+ * A run this instance cannot resume is SKIPPED, not allowed to abort the batch. The canonical
3894
+ * case is skew protection: mid-rolling-deploy a pod leases a run whose workflow it does not have
3895
+ * and `resume` throws by design — but the rest of the batch is runs it can drive perfectly well,
3896
+ * and every caller here is a recovery sweep. Letting the first such run end the loop means one
3897
+ * row stops recovery for the whole deployment, and (since the callers are pollers) sends the
3898
+ * rejection into a lifecycle hook. Skipping leaves the run locked only until its lease expires,
3899
+ * for a pod that does have the workflow — which is exactly what the skew-protection error asks
3900
+ * for. Same posture as `publishEvent`'s per-subscriber isolation.
3892
3901
  */
3893
3902
  async resumeLeased(runs, nowMs = this.clock(), onLocked) {
3894
3903
  if (this.draining) return [];
@@ -3896,8 +3905,12 @@ var WorkflowEngine = class {
3896
3905
  for (const run of runs) {
3897
3906
  const acquired = await this.store.tryLockRun(run.id, this.instanceId, nowMs + this.leaseMs, nowMs);
3898
3907
  if (!acquired) continue;
3899
- const settled = onLocked ? await onLocked(run) : void 0;
3900
- results.push(settled ?? await this.resume(run.id));
3908
+ try {
3909
+ const settled = onLocked ? await onLocked(run) : void 0;
3910
+ results.push(settled ?? await this.resume(run.id));
3911
+ } catch (error2) {
3912
+ console.error(`[nestjs-durable] could not resume run ${run.id} (${run.workflow}@${run.workflowVersion}); leaving it for another instance:`, error2);
3913
+ }
3901
3914
  }
3902
3915
  return results;
3903
3916
  }
@@ -6051,12 +6064,13 @@ function mergeRunValueFacetRows(rows, opts) {
6051
6064
  const value = row.value ?? null;
6052
6065
  counts.set(value, (counts.get(value) ?? 0) + Number(row.count));
6053
6066
  }
6067
+ const needle = opts?.search?.trim().toLowerCase();
6054
6068
  const merged = [
6055
6069
  ...counts
6056
6070
  ].map(([value, count]) => ({
6057
6071
  value,
6058
6072
  count
6059
- })).filter((row) => row.count > 0).sort((a, b) => {
6073
+ })).filter((row) => row.count > 0).filter((row) => !needle || row.value?.toLowerCase().includes(needle)).sort((a, b) => {
6060
6074
  const engineA = isEngineMintedTag(a.value);
6061
6075
  const engineB = isEngineMintedTag(b.value);
6062
6076
  if (engineA !== engineB) return engineA ? 1 : -1;
@@ -6065,7 +6079,8 @@ function mergeRunValueFacetRows(rows, opts) {
6065
6079
  if (b.value === null) return -1;
6066
6080
  return a.value.localeCompare(b.value);
6067
6081
  });
6068
- return merged.slice(0, opts?.limit ?? RUN_VALUE_FACET_LIMIT);
6082
+ const offset = opts?.offset ?? 0;
6083
+ return merged.slice(offset, offset + (opts?.limit ?? RUN_VALUE_FACET_LIMIT));
6069
6084
  }
6070
6085
  __name(mergeRunValueFacetRows, "mergeRunValueFacetRows");
6071
6086
  function runValueFacetsFromRuns(runs, axis, opts) {