@dudousxd/nestjs-durable-core 0.40.0 → 0.41.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
@@ -574,6 +574,15 @@ interface SignalWaiter {
574
574
  token: string;
575
575
  runId: string;
576
576
  seq: number;
577
+ /**
578
+ * The parallel-fan group this waiter belongs to, carried from the awaiting command so the resolving
579
+ * `signal:<token>` checkpoint (notably `signal:child:<id>` for an awaited child run) can be tagged
580
+ * with it. A worker's `ctx.gather_children`/`ctx.all` fan-out stamps every `startChild` with the same
581
+ * group; without threading it through the waiter, the child-await checkpoint comes out untagged and the
582
+ * dashboard renders the fan as a sequential chain instead of one parallel group. Undefined for an
583
+ * ordinary (non-fan) signal/child await.
584
+ */
585
+ parallelGroup?: string | undefined;
577
586
  }
578
587
  /** A unit of work dispatched to a remote worker. This is the documented wire payload. */
579
588
  interface RemoteTask {
@@ -674,13 +683,17 @@ interface HistoryEvent {
674
683
  }
675
684
  /** A decision the workflow function produced at a `seq` that was not yet in history. */
676
685
  type WorkflowCommand =
677
- /** `ctx.call(remoteStep, input)` — dispatch a remote step and await it. */
686
+ /** `ctx.call(remoteStep, input)` — dispatch a remote step and await it. A worker's
687
+ * `ctx.gather_calls([...])` fan-out tags every dispatched call with the same `parallelGroup` so the
688
+ * dashboard renders the remote steps as one parallel fan (parity with the gathered `recordStep` /
689
+ * `startChild` tags). Undefined for a lone sequential `ctx.call`. */
678
690
  {
679
691
  kind: 'call';
680
692
  seq: number;
681
693
  name: string;
682
694
  group: string;
683
695
  input: unknown;
696
+ parallelGroup?: string;
684
697
  }
685
698
  /** `ctx.step(name, body)` — a LOCAL step the worker already ran this turn; the engine persists its
686
699
  * result so replay returns it instead of re-running (durability for side-effectful work).
package/dist/index.d.ts CHANGED
@@ -574,6 +574,15 @@ interface SignalWaiter {
574
574
  token: string;
575
575
  runId: string;
576
576
  seq: number;
577
+ /**
578
+ * The parallel-fan group this waiter belongs to, carried from the awaiting command so the resolving
579
+ * `signal:<token>` checkpoint (notably `signal:child:<id>` for an awaited child run) can be tagged
580
+ * with it. A worker's `ctx.gather_children`/`ctx.all` fan-out stamps every `startChild` with the same
581
+ * group; without threading it through the waiter, the child-await checkpoint comes out untagged and the
582
+ * dashboard renders the fan as a sequential chain instead of one parallel group. Undefined for an
583
+ * ordinary (non-fan) signal/child await.
584
+ */
585
+ parallelGroup?: string | undefined;
577
586
  }
578
587
  /** A unit of work dispatched to a remote worker. This is the documented wire payload. */
579
588
  interface RemoteTask {
@@ -674,13 +683,17 @@ interface HistoryEvent {
674
683
  }
675
684
  /** A decision the workflow function produced at a `seq` that was not yet in history. */
676
685
  type WorkflowCommand =
677
- /** `ctx.call(remoteStep, input)` — dispatch a remote step and await it. */
686
+ /** `ctx.call(remoteStep, input)` — dispatch a remote step and await it. A worker's
687
+ * `ctx.gather_calls([...])` fan-out tags every dispatched call with the same `parallelGroup` so the
688
+ * dashboard renders the remote steps as one parallel fan (parity with the gathered `recordStep` /
689
+ * `startChild` tags). Undefined for a lone sequential `ctx.call`. */
678
690
  {
679
691
  kind: 'call';
680
692
  seq: number;
681
693
  name: string;
682
694
  group: string;
683
695
  input: unknown;
696
+ parallelGroup?: string;
684
697
  }
685
698
  /** `ctx.step(name, body)` — a LOCAL step the worker already ran this turn; the engine persists its
686
699
  * result so replay returns it instead of re-running (durability for side-effectful work).
package/dist/index.js CHANGED
@@ -1208,7 +1208,8 @@ function createWorkflowCtx(host, runId, compensations, workflow = "") {
1208
1208
  await store.putSignalWaiter({
1209
1209
  token: `child:${childId}`,
1210
1210
  runId,
1211
- seq
1211
+ seq,
1212
+ parallelGroup: group
1212
1213
  });
1213
1214
  if (!await store.getRun(childId)) host.startChild(name, inputs[i], childId);
1214
1215
  if (!cp) {
@@ -2283,7 +2284,12 @@ var WorkflowEngine = class {
2283
2284
  seq: waiter.seq,
2284
2285
  name: `signal:${token}`,
2285
2286
  kind: "signal",
2286
- output: payload
2287
+ output: payload,
2288
+ // Carry the awaiting command's fan group (set when a `ctx.gather_children`/`ctx.all` fan-out
2289
+ // registered this waiter) onto the resolving `signal:child:<id>` checkpoint, so the dashboard
2290
+ // groups the child fan-out vertically instead of rendering it as a sequential chain. Undefined
2291
+ // for an ordinary (non-fan) signal/child await.
2292
+ parallelGroup: waiter.parallelGroup
2287
2293
  }));
2288
2294
  return this.resume(waiter.runId).catch((err) => {
2289
2295
  if (err instanceof NamespaceMismatch) return null;
@@ -2984,6 +2990,7 @@ var WorkflowEngine = class {
2984
2990
  error: cmd.error
2985
2991
  });
2986
2992
  } else if (cmd.kind === "call") {
2993
+ if (await this.store.getCheckpoint(run.id, cmd.seq)) continue;
2987
2994
  await this.store.saveCheckpoint(stepCheckpoint({
2988
2995
  runId: run.id,
2989
2996
  seq: cmd.seq,
@@ -2995,7 +3002,11 @@ var WorkflowEngine = class {
2995
3002
  workerGroup: cmd.group,
2996
3003
  enqueuedAt: at,
2997
3004
  startedAt: at,
2998
- finishedAt: at
3005
+ finishedAt: at,
3006
+ // A `ctx.gather_calls([...])` fan-out stamps every dispatched `call` in the fan with the
3007
+ // same group, so the dashboard renders the remote steps as one parallel fan (parity with
3008
+ // the gathered `recordStep`/`startChild` tags). Undefined for a lone sequential `ctx.call`.
3009
+ parallelGroup: cmd.parallelGroup
2999
3010
  }));
3000
3011
  await this.pool.dispatch({
3001
3012
  runId: run.id,
@@ -3053,7 +3064,12 @@ var WorkflowEngine = class {
3053
3064
  await this.store.putSignalWaiter({
3054
3065
  token: `child:${childId}`,
3055
3066
  runId: run.id,
3056
- seq: cmd.seq
3067
+ seq: cmd.seq,
3068
+ // A `ctx.gather_children`/`ctx.all` fan-out stamps every `startChild` in the fan with the same
3069
+ // group. Thread it onto the waiter so the child's terminal `signal:child:<id>` checkpoint
3070
+ // (written by engine.signal when the child notifies the parent) carries the group and the
3071
+ // dashboard renders the fan as one parallel group. Undefined for a lone (non-fan) child.
3072
+ parallelGroup: cmd.parallelGroup
3057
3073
  });
3058
3074
  if (!await this.store.getRun(childId)) {
3059
3075
  queueMicrotask(() => void this.start(cmd.workflow, cmd.input, childId).catch(() => void 0));