@dudousxd/nestjs-durable-core 0.75.1 → 0.75.2

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 CHANGED
@@ -3861,6 +3861,12 @@ var WorkflowEngine = class {
3861
3861
  updateValidators = /* @__PURE__ */ new Map();
3862
3862
  /** Runs being cancelled WITH saga compensation — see `cancel({ compensate: true })`. */
3863
3863
  cancelRequested = /* @__PURE__ */ new Set();
3864
+ /**
3865
+ * Seqs of the dispatched remote steps a turn suspended on, by run, while that turn executes on
3866
+ * THIS instance — so the turn can re-check them once its lease is released (see
3867
+ * {@link redriveSettledSteps}).
3868
+ */
3869
+ awaitedRemoteSteps = /* @__PURE__ */ new Map();
3864
3870
  /** Flow-control admission backend for remote steps (see {@link registerQueue}). */
3865
3871
  admission;
3866
3872
  /** Runs on THIS instance blocked on admission, by queue — woken early on a freed-slot signal. */
@@ -5264,6 +5270,24 @@ var WorkflowEngine = class {
5264
5270
  * itself. Only re-drives for a group with no waiter left whose checkpoints are all settled, which
5265
5271
  * the next turn is then guaranteed to see — so it cannot loop.
5266
5272
  */
5273
+ /**
5274
+ * Re-drive a run that just suspended on dispatched remote steps which, by now, have a result.
5275
+ *
5276
+ * Same race as {@link redriveSettledChildren}, for `ctx.step`: a result landing while the turn
5277
+ * that dispatched it still holds the lease has its wake dropped by {@link execute}, and the turn
5278
+ * then suspends with nothing left to wake it before the step's redispatch deadline. Called after
5279
+ * the lease is released, so any later result wakes the run itself; it only re-drives for a
5280
+ * checkpoint that is already settled, which the next turn replays past — so it cannot loop.
5281
+ */
5282
+ async redriveSettledSteps(runId, seqs) {
5283
+ for (const seq of seqs) {
5284
+ const cp = await this.store.getCheckpoint(runId, seq);
5285
+ if (cp && (cp.status === "completed" || cp.status === "failed")) {
5286
+ await this.resumeImplicit(runId);
5287
+ return;
5288
+ }
5289
+ }
5290
+ }
5267
5291
  async redriveSettledChildren(runId, fan) {
5268
5292
  if (!this.store.hasSignalWaiter) return;
5269
5293
  for (const wait of fan.waits) {
@@ -6718,6 +6742,9 @@ var WorkflowEngine = class {
6718
6742
  const replay = /* @__PURE__ */ new Map();
6719
6743
  for (const cp of snapshot) replay.set(cp.seq, cp);
6720
6744
  let suspendedOnFan;
6745
+ let suspendedOnSteps = false;
6746
+ const awaitedSteps = /* @__PURE__ */ new Set();
6747
+ this.awaitedRemoteSteps.set(run.id, awaitedSteps);
6721
6748
  const ctx = createWorkflowCtx(this.ctxHostFor(replay, run.namespace), run.id, compensations, run.workflow, registered?.searchAttributesSchema);
6722
6749
  try {
6723
6750
  const output = await runInWorkflowCtx(ctx, () => fn(ctx, run.input));
@@ -6774,6 +6801,7 @@ var WorkflowEngine = class {
6774
6801
  wakeAt: err.wakeAt
6775
6802
  });
6776
6803
  suspendedOnFan = err.fan;
6804
+ suspendedOnSteps = suspended.status === "suspended";
6777
6805
  return suspended;
6778
6806
  }
6779
6807
  if (this.cancelRequested.has(run.id)) {
@@ -6793,10 +6821,16 @@ var WorkflowEngine = class {
6793
6821
  error: error2
6794
6822
  });
6795
6823
  } finally {
6824
+ if (this.awaitedRemoteSteps.get(run.id) === awaitedSteps) {
6825
+ this.awaitedRemoteSteps.delete(run.id);
6826
+ }
6796
6827
  await this.store.releaseRunLock(run.id);
6797
6828
  if (suspendedOnFan) {
6798
6829
  void this.redriveSettledChildren(run.id, suspendedOnFan).catch(() => void 0);
6799
6830
  }
6831
+ if (suspendedOnSteps && awaitedSteps.size > 0) {
6832
+ void this.redriveSettledSteps(run.id, awaitedSteps).catch(() => void 0);
6833
+ }
6800
6834
  }
6801
6835
  }
6802
6836
  /**
@@ -7216,6 +7250,7 @@ var WorkflowEngine = class {
7216
7250
  if (this.pool.size === 0) throw new Error("remote steps require a Transport");
7217
7251
  if (step.timeoutMs) return this.callRemoteInMemory(runId, seq, step, input, transport, group);
7218
7252
  if (existing?.status === "pending") {
7253
+ this.awaitedRemoteSteps.get(runId)?.add(seq);
7219
7254
  if (this.remoteRedispatchMs == null) throw new WorkflowSuspended();
7220
7255
  if (existing.wakeAt == null) {
7221
7256
  const wakeAt = this.clock() + this.remoteRedispatchMs;
@@ -7336,6 +7371,7 @@ var WorkflowEngine = class {
7336
7371
  name: step.name,
7337
7372
  kind: "remote"
7338
7373
  });
7374
+ this.awaitedRemoteSteps.get(runId)?.add(seq);
7339
7375
  throw new WorkflowSuspended();
7340
7376
  }
7341
7377
  /** Enqueue a remote step task to its worker group via the transport pool. Shared by the initial