@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 CHANGED
@@ -68,6 +68,7 @@ __export(index_exports, {
68
68
  canRoute: () => canRoute,
69
69
  capableWorkers: () => capableWorkers,
70
70
  classifyWaiterToken: () => classifyWaiterToken,
71
+ clearDurableExecutionWrappers: () => clearDurableExecutionWrappers,
71
72
  collectMetrics: () => collectMetrics,
72
73
  controlPlaneDescriptor: () => controlPlaneDescriptor,
73
74
  createStepLogger: () => createStepLogger,
@@ -81,6 +82,7 @@ __export(index_exports, {
81
82
  eventNameOf: () => eventNameOf,
82
83
  eventPrefix: () => eventPrefix,
83
84
  eventToken: () => eventToken,
85
+ hasDurableExecutionWrappers: () => hasDurableExecutionWrappers,
84
86
  heartbeatStatus: () => heartbeatStatus,
85
87
  indexWaitersByRun: () => indexWaitersByRun,
86
88
  info: () => info,
@@ -100,6 +102,7 @@ __export(index_exports, {
100
102
  requiredCapabilities: () => requiredCapabilities,
101
103
  resolveRouting: () => resolveRouting,
102
104
  resolveRunWaiting: () => resolveRunWaiting,
105
+ runDurableExecution: () => runDurableExecution,
103
106
  runInStepLogger: () => runInStepLogger,
104
107
  runInWorkflowCtx: () => runInWorkflowCtx,
105
108
  runSchedules: () => runSchedules,
@@ -114,6 +117,7 @@ __export(index_exports, {
114
117
  subEvent: () => subEvent,
115
118
  subProcess: () => subProcess,
116
119
  tenantGroup: () => tenantGroup,
120
+ useDurableExecution: () => useDurableExecution,
117
121
  warn: () => warn,
118
122
  workflowName: () => workflowName
119
123
  });
@@ -599,6 +603,57 @@ function backoffDelay(attempt, options) {
599
603
  }
600
604
  __name(backoffDelay, "backoffDelay");
601
605
 
606
+ // src/execution-hooks.ts
607
+ var wrappers = [];
608
+ function useDurableExecution(wrapper) {
609
+ wrappers.push(wrapper);
610
+ return () => {
611
+ const i = wrappers.indexOf(wrapper);
612
+ if (i >= 0) wrappers.splice(i, 1);
613
+ };
614
+ }
615
+ __name(useDurableExecution, "useDurableExecution");
616
+ function clearDurableExecutionWrappers() {
617
+ wrappers.length = 0;
618
+ }
619
+ __name(clearDurableExecutionWrappers, "clearDurableExecutionWrappers");
620
+ function hasDurableExecutionWrappers() {
621
+ return wrappers.length > 0;
622
+ }
623
+ __name(hasDurableExecutionWrappers, "hasDurableExecutionWrappers");
624
+ async function runDurableExecution(execution, body) {
625
+ if (wrappers.length === 0) return body();
626
+ let outcome;
627
+ const inner = /* @__PURE__ */ __name(async () => {
628
+ try {
629
+ const value = await body();
630
+ outcome = {
631
+ ok: true,
632
+ value
633
+ };
634
+ return value;
635
+ } catch (error2) {
636
+ outcome = {
637
+ ok: false,
638
+ error: error2
639
+ };
640
+ throw error2;
641
+ }
642
+ }, "inner");
643
+ const chain = wrappers.reduceRight((next, wrapper) => () => wrapper(execution, next), inner);
644
+ try {
645
+ await chain();
646
+ } catch (error2) {
647
+ if (outcome === void 0) throw error2;
648
+ }
649
+ if (outcome === void 0) {
650
+ throw new Error("a durable execution wrapper returned without calling next() \u2014 the unit of work never ran");
651
+ }
652
+ if (outcome.ok) return outcome.value;
653
+ throw outcome.error;
654
+ }
655
+ __name(runDurableExecution, "runDurableExecution");
656
+
602
657
  // src/step-logger.ts
603
658
  function withDuration(start, now, data) {
604
659
  if (data && typeof data === "object" && "durationMs" in data) {
@@ -740,7 +795,14 @@ async function runStepHandler(task, handler) {
740
795
  } : result, "withEvents");
741
796
  try {
742
797
  const logger = createStepLogger(events, Date.now);
743
- const output = await runInStepLogger(logger, () => handler(task.input, logger));
798
+ const output = await runDurableExecution({
799
+ unit: "step",
800
+ runId: task.runId,
801
+ workflow: void 0,
802
+ name: task.name,
803
+ seq: task.seq,
804
+ attempt: task.attempt
805
+ }, async () => runInStepLogger(logger, () => handler(task.input, logger)));
744
806
  return withEvents({
745
807
  ...base,
746
808
  status: "completed",
@@ -2676,6 +2738,7 @@ var WorkflowEngine = class {
2676
2738
  onEvent: opts?.onEvent,
2677
2739
  eventBatch: opts?.eventBatch,
2678
2740
  requires: opts?.requires,
2741
+ origin: opts?.origin,
2679
2742
  // A real, retained in-process body — so `workflowBody` can hand it to an in-app worker, and so
2680
2743
  // it is NOT confused with the throwing stub `registerRemote` installs for a body-less remote.
2681
2744
  hasBody: true
@@ -2902,6 +2965,11 @@ var WorkflowEngine = class {
2902
2965
  workflowVersion: registered.version,
2903
2966
  status: "pending",
2904
2967
  namespace: opts?.namespace ?? this.namespace,
2968
+ // DERIVED from the registration, exactly like `namespace` is derived from this engine — there is
2969
+ // deliberately no `opts.origin`, so a caller cannot label its run as another package's work.
2970
+ // `undefined` when the registration carried none (remote/convention/synthesized child, or a
2971
+ // registrar that could not resolve the declaring package): unknown, not "the app".
2972
+ origin: registered.origin,
2905
2973
  input,
2906
2974
  tags,
2907
2975
  searchAttributes: opts?.searchAttributes,
@@ -4636,8 +4704,31 @@ var WorkflowEngine = class {
4636
4704
  error: error2
4637
4705
  };
4638
4706
  }
4639
- /** The run body, lease held + renewed by {@link execute}. */
4640
- async runExecution(run, fn, registered) {
4707
+ /**
4708
+ * The run body, lease held + renewed by {@link execute}, wrapped in the registered
4709
+ * {@link runDurableExecution} wrappers so an observability scope covers ONE WHOLE TURN.
4710
+ *
4711
+ * The wrap goes here — around the entire turn — rather than tightly around the `fn(ctx, input)`
4712
+ * call, because the store writes that bracket the body (the `pending` → `running` transition, the
4713
+ * step checkpoints, the terminal `settleRun` update) are exactly the queries an operator wants
4714
+ * correlated to the turn that issued them. Narrowing the wrap to the body would leave them
4715
+ * uncorrelated for the sake of a purity that buys nothing.
4716
+ *
4717
+ * Only the TS path is wrapped. {@link runRemoteExecution} does not execute a body at all — it
4718
+ * dispatches a workflow task and awaits the worker's decision — so a scope opened there would
4719
+ * describe a dispatch, not an execution, and would mislead anyone reading the trace.
4720
+ */
4721
+ runExecution(run, fn, registered) {
4722
+ return runDurableExecution({
4723
+ unit: "workflow",
4724
+ runId: run.id,
4725
+ workflow: run.workflow,
4726
+ name: void 0,
4727
+ seq: void 0,
4728
+ attempt: void 0
4729
+ }, () => this.runExecutionTurn(run, fn, registered));
4730
+ }
4731
+ async runExecutionTurn(run, fn, registered) {
4641
4732
  if (run.status === "cancelling") this.cancelRequested.add(run.id);
4642
4733
  if (run.status === "pending") {
4643
4734
  await this.store.updateRun(run.id, {
@@ -6247,6 +6338,7 @@ var InMemoryStateStore = class {
6247
6338
  if (query.statuses) runs = runs.filter((r) => query.statuses?.includes(r.status));
6248
6339
  if (query.tag) runs = runs.filter((r) => r.tags?.includes(query.tag));
6249
6340
  if (query.namespace !== void 0) runs = runs.filter((r) => r.namespace === query.namespace);
6341
+ if (query.origin !== void 0) runs = runs.filter((r) => r.origin === query.origin);
6250
6342
  if (query.attributes?.length) {
6251
6343
  let candidates = null;
6252
6344
  for (const f of query.attributes) {
@@ -6396,6 +6488,7 @@ var InMemoryTransport = class {
6396
6488
  canRoute,
6397
6489
  capableWorkers,
6398
6490
  classifyWaiterToken,
6491
+ clearDurableExecutionWrappers,
6399
6492
  collectMetrics,
6400
6493
  controlPlaneDescriptor,
6401
6494
  createStepLogger,
@@ -6409,6 +6502,7 @@ var InMemoryTransport = class {
6409
6502
  eventNameOf,
6410
6503
  eventPrefix,
6411
6504
  eventToken,
6505
+ hasDurableExecutionWrappers,
6412
6506
  heartbeatStatus,
6413
6507
  indexWaitersByRun,
6414
6508
  info,
@@ -6428,6 +6522,7 @@ var InMemoryTransport = class {
6428
6522
  requiredCapabilities,
6429
6523
  resolveRouting,
6430
6524
  resolveRunWaiting,
6525
+ runDurableExecution,
6431
6526
  runInStepLogger,
6432
6527
  runInWorkflowCtx,
6433
6528
  runSchedules,
@@ -6442,6 +6537,7 @@ var InMemoryTransport = class {
6442
6537
  subEvent,
6443
6538
  subProcess,
6444
6539
  tenantGroup,
6540
+ useDurableExecution,
6445
6541
  warn,
6446
6542
  workflowName
6447
6543
  });