@dudousxd/nestjs-durable 0.47.1 → 0.48.1

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
@@ -49,14 +49,16 @@ __export(index_exports, {
49
49
  IN_APP_WORKER_RUNNERS: () => IN_APP_WORKER_RUNNERS,
50
50
  IN_APP_WORKER_RUNTIME: () => IN_APP_WORKER_RUNTIME,
51
51
  InAppWorkerBootstrap: () => InAppWorkerBootstrap,
52
+ ON_ERROR_METADATA: () => ON_ERROR_METADATA,
52
53
  ON_EVENT_METADATA: () => ON_EVENT_METADATA,
53
54
  On: () => On,
54
55
  OnDurableEvent: () => OnDurableEvent,
56
+ OnError: () => OnError,
55
57
  OnEvent: () => OnEvent,
56
58
  ProxyRunGateway: () => ProxyRunGateway,
57
59
  RUN_GATEWAY: () => RUN_GATEWAY,
58
60
  RUN_REDIS_WORKER: () => RUN_REDIS_WORKER,
59
- RunGateway: () => import_nestjs_durable_core15.RunGateway,
61
+ RunGateway: () => import_nestjs_durable_core17.RunGateway,
60
62
  RunRequestResponder: () => RunRequestResponder,
61
63
  STEP_INTERCEPTOR_METADATA: () => STEP_INTERCEPTOR_METADATA,
62
64
  Step: () => Step,
@@ -66,9 +68,10 @@ __export(index_exports, {
66
68
  ThinStepRegistrar: () => ThinStepRegistrar,
67
69
  ThinWorkerBootstrap: () => ThinWorkerBootstrap,
68
70
  ThinWorkflowRegistrar: () => ThinWorkflowRegistrar,
71
+ UNSUPPORTED_RUN_REQUEST: () => UNSUPPORTED_RUN_REQUEST,
69
72
  WORKFLOW_METADATA: () => WORKFLOW_METADATA,
70
73
  Workflow: () => Workflow,
71
- WorkflowEngine: () => import_nestjs_durable_core15.WorkflowEngine,
74
+ WorkflowEngine: () => import_nestjs_durable_core17.WorkflowEngine,
72
75
  WorkflowService: () => WorkflowService,
73
76
  attributesOf: () => attributesOf,
74
77
  entityConfigFor: () => entityConfigFor,
@@ -81,7 +84,8 @@ __export(index_exports, {
81
84
  isDrivingOperator: () => isDrivingOperator,
82
85
  isOperatorRole: () => isOperatorRole,
83
86
  isStepInterceptor: () => isStepInterceptor,
84
- readSearchAttributes: () => import_nestjs_durable_core15.readSearchAttributes,
87
+ onErrorCodesOf: () => onErrorCodesOf,
88
+ readSearchAttributes: () => import_nestjs_durable_core17.readSearchAttributes,
85
89
  thinWorkerProviders: () => thinWorkerProviders,
86
90
  unavailableRunGateway: () => unavailableRunGateway
87
91
  });
@@ -211,6 +215,7 @@ function Workflow(options) {
211
215
  name: options.name,
212
216
  version: options.version ?? "1",
213
217
  deadLetterWorkflow: options.deadLetterWorkflow,
218
+ onError: options.onError,
214
219
  tags: options.tags,
215
220
  singleton: options.singleton,
216
221
  concurrency: options.concurrency,
@@ -288,6 +293,26 @@ function isDeadLetterHandler(method) {
288
293
  return Reflect.getMetadata(DEAD_LETTER_METADATA, method) === true;
289
294
  }
290
295
  __name(isDeadLetterHandler, "isDeadLetterHandler");
296
+ var ON_ERROR_METADATA = Symbol("nestjs-durable:on-error");
297
+ function OnError(match) {
298
+ const code = match === void 0 || typeof match === "string" ? match : match.code;
299
+ if (match !== void 0 && typeof code !== "string") {
300
+ throw new Error('@OnError(ErrorClass): the class has no static `code`. Declare `static readonly code = "..."` on it, or pass the code string.');
301
+ }
302
+ return (_target, _propertyKey, descriptor) => {
303
+ const method = descriptor.value;
304
+ const codes = Reflect.getMetadata(ON_ERROR_METADATA, method) ?? [];
305
+ Reflect.defineMetadata(ON_ERROR_METADATA, [
306
+ ...codes,
307
+ code
308
+ ], method);
309
+ };
310
+ }
311
+ __name(OnError, "OnError");
312
+ function onErrorCodesOf(method) {
313
+ return Reflect.getMetadata(ON_ERROR_METADATA, method);
314
+ }
315
+ __name(onErrorCodesOf, "onErrorCodesOf");
291
316
  var ON_EVENT_METADATA = Symbol("nestjs-durable:on-event");
292
317
  function OnDurableEvent(...events) {
293
318
  return (target) => {
@@ -449,7 +474,7 @@ function tenantUnsupported(method) {
449
474
  __name(tenantUnsupported, "tenantUnsupported");
450
475
 
451
476
  // src/durable-worker.module.ts
452
- var import_nestjs_durable_core4 = require("@dudousxd/nestjs-durable-core");
477
+ var import_nestjs_durable_core5 = require("@dudousxd/nestjs-durable-core");
453
478
  var import_common2 = require("@nestjs/common");
454
479
  var import_core = require("@nestjs/core");
455
480
 
@@ -490,6 +515,66 @@ function scanSteps(discovery, scanner, register) {
490
515
  }
491
516
  __name(scanSteps, "scanSteps");
492
517
 
518
+ // src/on-error-handlers.ts
519
+ var import_nestjs_durable_core4 = require("@dudousxd/nestjs-durable-core");
520
+ function onErrorHandlersOf(meta, instance, scanner) {
521
+ const handlers = [];
522
+ const routes = [];
523
+ for (const methodName of scanner.getAllMethodNames(Object.getPrototypeOf(instance))) {
524
+ const method = instance[methodName];
525
+ const codes = typeof method === "function" ? onErrorCodesOf(method) : void 0;
526
+ if (!codes) continue;
527
+ const name = `${meta.name}.onError.${methodName}`;
528
+ handlers.push([
529
+ name,
530
+ (ctx, input) => method.call(instance, ctx, input)
531
+ ]);
532
+ for (const code of codes) routes.push({
533
+ code,
534
+ workflow: name
535
+ });
536
+ }
537
+ for (const r of meta.onError ?? []) {
538
+ routes.push({
539
+ code: r.code === void 0 || typeof r.code === "string" ? r.code : r.code.code,
540
+ workflow: (0, import_nestjs_durable_core4.workflowName)(r.workflow)
541
+ });
542
+ }
543
+ return {
544
+ handlers,
545
+ routes
546
+ };
547
+ }
548
+ __name(onErrorHandlersOf, "onErrorHandlersOf");
549
+
550
+ // src/runtime-registration.ts
551
+ function registerOnRuntime(runtime, scanner, meta, instance, origin) {
552
+ const { handlers, routes } = onErrorHandlersOf(meta, instance, scanner);
553
+ const announced = {
554
+ version: meta.version,
555
+ ...origin !== void 0 ? {
556
+ origin
557
+ } : {}
558
+ };
559
+ runtime.registerWorkflow(meta.name, (ctx, input) => instance.run(ctx, input), {
560
+ ...announced,
561
+ ...meta.requires !== void 0 ? {
562
+ requires: meta.requires
563
+ } : {},
564
+ // A catch-all goes on the wire without a `code` key, not with an undefined one.
565
+ ...routes.length > 0 ? {
566
+ onError: routes.map(({ code, workflow }) => code === void 0 ? {
567
+ workflow
568
+ } : {
569
+ code,
570
+ workflow
571
+ })
572
+ } : {}
573
+ });
574
+ for (const [name, fn] of handlers) runtime.registerWorkflow(name, fn, announced);
575
+ }
576
+ __name(registerOnRuntime, "registerOnRuntime");
577
+
493
578
  // src/durable-worker.module.ts
494
579
  function _ts_decorate2(decorators, target, key, desc) {
495
580
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -529,34 +614,29 @@ var ThinWorkflowRegistrar = class {
529
614
  __name(this, "ThinWorkflowRegistrar");
530
615
  }
531
616
  discovery;
617
+ metadataScanner;
532
618
  runtime;
533
619
  options;
534
- constructor(discovery, runtime, options) {
620
+ constructor(discovery, metadataScanner, runtime, options) {
535
621
  this.discovery = discovery;
622
+ this.metadataScanner = metadataScanner;
536
623
  this.runtime = runtime;
537
624
  this.options = options;
538
625
  }
539
626
  onModuleInit() {
540
627
  const runtime = this.runtime;
541
628
  if (runtime === null || !isPureThinWorker(this.options)) return;
542
- scanWorkflows(this.discovery, (meta, instance, origin) => runtime.registerWorkflow(meta.name, (ctx, input) => instance.run(ctx, input), {
543
- version: meta.version,
544
- ...meta.requires !== void 0 ? {
545
- requires: meta.requires
546
- } : {},
547
- ...origin !== void 0 ? {
548
- origin
549
- } : {}
550
- }));
629
+ scanWorkflows(this.discovery, (meta, instance, origin) => registerOnRuntime(runtime, this.metadataScanner, meta, instance, origin));
551
630
  }
552
631
  };
553
632
  ThinWorkflowRegistrar = _ts_decorate2([
554
633
  (0, import_common2.Injectable)(),
555
- _ts_param(1, (0, import_common2.Inject)(DURABLE_WORKER_RUNTIME)),
556
- _ts_param(2, (0, import_common2.Inject)(import_nestjs_durable_core4.DURABLE_OPTIONS_CANONICAL)),
634
+ _ts_param(2, (0, import_common2.Inject)(DURABLE_WORKER_RUNTIME)),
635
+ _ts_param(3, (0, import_common2.Inject)(import_nestjs_durable_core5.DURABLE_OPTIONS_CANONICAL)),
557
636
  _ts_metadata2("design:type", Function),
558
637
  _ts_metadata2("design:paramtypes", [
559
638
  typeof import_core.DiscoveryService === "undefined" ? Object : import_core.DiscoveryService,
639
+ typeof import_core.MetadataScanner === "undefined" ? Object : import_core.MetadataScanner,
560
640
  Object,
561
641
  typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions
562
642
  ])
@@ -584,7 +664,7 @@ var ThinStepRegistrar = class {
584
664
  ThinStepRegistrar = _ts_decorate2([
585
665
  (0, import_common2.Injectable)(),
586
666
  _ts_param(2, (0, import_common2.Inject)(DURABLE_WORKER_RUNTIME)),
587
- _ts_param(3, (0, import_common2.Inject)(import_nestjs_durable_core4.DURABLE_OPTIONS_CANONICAL)),
667
+ _ts_param(3, (0, import_common2.Inject)(import_nestjs_durable_core5.DURABLE_OPTIONS_CANONICAL)),
588
668
  _ts_metadata2("design:type", Function),
589
669
  _ts_metadata2("design:paramtypes", [
590
670
  typeof import_core.DiscoveryService === "undefined" ? Object : import_core.DiscoveryService,
@@ -612,6 +692,7 @@ var ThinWorkerBootstrap = class {
612
692
  const options = this.options;
613
693
  const runtime = this.runtime;
614
694
  if (runtime === null || !isPureThinWorker(options) || options.connection === void 0) return;
695
+ if (options.consumers === false) return;
615
696
  const handle = await this.runRedisWorker({
616
697
  runtime,
617
698
  connection: options.connection,
@@ -638,7 +719,7 @@ var ThinWorkerBootstrap = class {
638
719
  ThinWorkerBootstrap = _ts_decorate2([
639
720
  (0, import_common2.Injectable)(),
640
721
  _ts_param(0, (0, import_common2.Inject)(DURABLE_WORKER_RUNTIME)),
641
- _ts_param(1, (0, import_common2.Inject)(import_nestjs_durable_core4.DURABLE_OPTIONS_CANONICAL)),
722
+ _ts_param(1, (0, import_common2.Inject)(import_nestjs_durable_core5.DURABLE_OPTIONS_CANONICAL)),
642
723
  _ts_param(2, (0, import_common2.Inject)(RUN_REDIS_WORKER)),
643
724
  _ts_param(3, (0, import_common2.Inject)(DURABLE_WORKER_RUNNERS)),
644
725
  _ts_metadata2("design:type", Function),
@@ -668,7 +749,7 @@ function thinWorkerProviders() {
668
749
  workflowGroup: options.partition ?? ""
669
750
  }) : null, "useFactory"),
670
751
  inject: [
671
- import_nestjs_durable_core4.DURABLE_OPTIONS_CANONICAL
752
+ import_nestjs_durable_core5.DURABLE_OPTIONS_CANONICAL
672
753
  ]
673
754
  },
674
755
  {
@@ -738,12 +819,12 @@ function unavailableRunGateway() {
738
819
  __name(unavailableRunGateway, "unavailableRunGateway");
739
820
 
740
821
  // src/durable.module.ts
741
- var import_nestjs_durable_core14 = require("@dudousxd/nestjs-durable-core");
822
+ var import_nestjs_durable_core16 = require("@dudousxd/nestjs-durable-core");
742
823
  var import_common12 = require("@nestjs/common");
743
824
  var import_core5 = require("@nestjs/core");
744
825
 
745
826
  // src/durable-step.registrar.ts
746
- var import_nestjs_durable_core5 = require("@dudousxd/nestjs-durable-core");
827
+ var import_nestjs_durable_core6 = require("@dudousxd/nestjs-durable-core");
747
828
  var import_common3 = require("@nestjs/common");
748
829
  var import_core2 = require("@nestjs/core");
749
830
 
@@ -811,8 +892,8 @@ var DurableStepRegistrar = class {
811
892
  };
812
893
  DurableStepRegistrar = _ts_decorate3([
813
894
  (0, import_common3.Injectable)(),
814
- _ts_param2(2, (0, import_common3.Inject)(import_nestjs_durable_core5.TRANSPORT_CANONICAL)),
815
- _ts_param2(3, (0, import_common3.Inject)(import_nestjs_durable_core5.DURABLE_OPTIONS_CANONICAL)),
895
+ _ts_param2(2, (0, import_common3.Inject)(import_nestjs_durable_core6.TRANSPORT_CANONICAL)),
896
+ _ts_param2(3, (0, import_common3.Inject)(import_nestjs_durable_core6.DURABLE_OPTIONS_CANONICAL)),
816
897
  _ts_metadata3("design:type", Function),
817
898
  _ts_metadata3("design:paramtypes", [
818
899
  typeof import_core2.DiscoveryService === "undefined" ? Object : import_core2.DiscoveryService,
@@ -823,7 +904,7 @@ DurableStepRegistrar = _ts_decorate3([
823
904
  ], DurableStepRegistrar);
824
905
 
825
906
  // src/entity.ts
826
- var import_nestjs_durable_core6 = require("@dudousxd/nestjs-durable-core");
907
+ var import_nestjs_durable_core7 = require("@dudousxd/nestjs-durable-core");
827
908
  var import_common4 = require("@nestjs/common");
828
909
  var import_reflect_metadata2 = require("reflect-metadata");
829
910
  function _ts_decorate4(decorators, target, key, desc) {
@@ -906,12 +987,12 @@ EntityService = _ts_decorate4([
906
987
  (0, import_common4.Injectable)(),
907
988
  _ts_metadata4("design:type", Function),
908
989
  _ts_metadata4("design:paramtypes", [
909
- typeof import_nestjs_durable_core6.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core6.WorkflowEngine
990
+ typeof import_nestjs_durable_core7.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core7.WorkflowEngine
910
991
  ])
911
992
  ], EntityService);
912
993
 
913
994
  // src/in-app-worker.ts
914
- var import_nestjs_durable_core7 = require("@dudousxd/nestjs-durable-core");
995
+ var import_nestjs_durable_core8 = require("@dudousxd/nestjs-durable-core");
915
996
  var import_common5 = require("@nestjs/common");
916
997
  var import_core3 = require("@nestjs/core");
917
998
  function _ts_decorate5(decorators, target, key, desc) {
@@ -983,21 +1064,14 @@ var InAppWorkerBootstrap = class {
983
1064
  onModuleInit() {
984
1065
  const runtime = this.runtime;
985
1066
  if (runtime === null || !isCoLocatedWorker(this.options)) return;
986
- scanWorkflows(this.discovery, (meta, instance, origin) => runtime.registerWorkflow(meta.name, (ctx, input) => instance.run(ctx, input), {
987
- version: meta.version,
988
- ...meta.requires !== void 0 ? {
989
- requires: meta.requires
990
- } : {},
991
- ...origin !== void 0 ? {
992
- origin
993
- } : {}
994
- }));
1067
+ scanWorkflows(this.discovery, (meta, instance, origin) => registerOnRuntime(runtime, this.metadataScanner, meta, instance, origin));
995
1068
  scanSteps(this.discovery, this.metadataScanner, (meta, handler) => runtime.registerStep(meta.name, handler));
996
1069
  }
997
1070
  async onApplicationBootstrap() {
998
1071
  const options = this.options;
999
1072
  const runtime = this.runtime;
1000
1073
  if (runtime === null || !isCoLocatedWorker(options) || options.connection === void 0) return;
1074
+ if (options.consumers === false) return;
1001
1075
  const handle = await this.runRedisWorker({
1002
1076
  runtime,
1003
1077
  connection: options.connection,
@@ -1023,7 +1097,7 @@ var InAppWorkerBootstrap = class {
1023
1097
  };
1024
1098
  InAppWorkerBootstrap = _ts_decorate5([
1025
1099
  (0, import_common5.Injectable)(),
1026
- _ts_param3(2, (0, import_common5.Inject)(import_nestjs_durable_core7.DURABLE_OPTIONS_CANONICAL)),
1100
+ _ts_param3(2, (0, import_common5.Inject)(import_nestjs_durable_core8.DURABLE_OPTIONS_CANONICAL)),
1027
1101
  _ts_param3(3, (0, import_common5.Inject)(IN_APP_WORKER_RUNTIME)),
1028
1102
  _ts_param3(4, (0, import_common5.Inject)(IN_APP_RUN_REDIS_WORKER)),
1029
1103
  _ts_param3(5, (0, import_common5.Inject)(IN_APP_WORKER_RUNNERS)),
@@ -1043,8 +1117,8 @@ function inAppWorkerProviders() {
1043
1117
  provide: IN_APP_WORKER_BINDING,
1044
1118
  useFactory: /* @__PURE__ */ __name((transport, options) => inAppWorkerBinding(transport, options), "useFactory"),
1045
1119
  inject: [
1046
- import_nestjs_durable_core7.TRANSPORT_CANONICAL,
1047
- import_nestjs_durable_core7.DURABLE_OPTIONS_CANONICAL
1120
+ import_nestjs_durable_core8.TRANSPORT_CANONICAL,
1121
+ import_nestjs_durable_core8.DURABLE_OPTIONS_CANONICAL
1048
1122
  ]
1049
1123
  },
1050
1124
  {
@@ -1064,7 +1138,7 @@ function inAppWorkerProviders() {
1064
1138
  workflowGroup: options.partition ?? ""
1065
1139
  }) : null, "useFactory"),
1066
1140
  inject: [
1067
- import_nestjs_durable_core7.DURABLE_OPTIONS_CANONICAL
1141
+ import_nestjs_durable_core8.DURABLE_OPTIONS_CANONICAL
1068
1142
  ]
1069
1143
  },
1070
1144
  {
@@ -1081,7 +1155,212 @@ function inAppWorkerProviders() {
1081
1155
  __name(inAppWorkerProviders, "inAppWorkerProviders");
1082
1156
 
1083
1157
  // src/proxy-run-gateway.ts
1158
+ var import_nestjs_durable_core9 = require("@dudousxd/nestjs-durable-core");
1084
1159
  var import_common6 = require("@nestjs/common");
1160
+
1161
+ // src/run-request-responder.ts
1162
+ var UNSUPPORTED_RUN_REQUEST = "unsupported-request";
1163
+ var KNOWN_KINDS = /* @__PURE__ */ new Set([
1164
+ "getRunDetail",
1165
+ "getFanMembers",
1166
+ "listRuns",
1167
+ "runFacets",
1168
+ "runValueFacets",
1169
+ "workerHealth",
1170
+ "cancel",
1171
+ "retry",
1172
+ "continue",
1173
+ "retryWithInput",
1174
+ "redispatch",
1175
+ "waitingFor"
1176
+ ]);
1177
+ var RunRequestResponder = class {
1178
+ static {
1179
+ __name(this, "RunRequestResponder");
1180
+ }
1181
+ transport;
1182
+ gateway;
1183
+ constructor(transport, gateway) {
1184
+ this.transport = transport;
1185
+ this.gateway = gateway;
1186
+ }
1187
+ /** Register the consumer on the transport. Each request is answered independently; a handler
1188
+ * failure never throws back into the transport (errors are captured into an error reply). */
1189
+ start() {
1190
+ this.transport.onRunRequest(async (msg) => {
1191
+ let reply;
1192
+ try {
1193
+ reply = await this.handle(msg);
1194
+ } catch (err) {
1195
+ reply = {
1196
+ requestId: msg.requestId,
1197
+ result: {
1198
+ ok: false,
1199
+ error: {
1200
+ message: err instanceof Error ? err.message : String(err)
1201
+ }
1202
+ }
1203
+ };
1204
+ }
1205
+ await this.transport.publishRunReply(reply);
1206
+ });
1207
+ }
1208
+ async handle(msg) {
1209
+ const { body } = msg;
1210
+ if (!KNOWN_KINDS.has(body.kind)) {
1211
+ return {
1212
+ requestId: msg.requestId,
1213
+ result: {
1214
+ ok: false,
1215
+ error: {
1216
+ message: `the control plane does not support the ${String(body.kind)} run request`,
1217
+ code: UNSUPPORTED_RUN_REQUEST
1218
+ }
1219
+ }
1220
+ };
1221
+ }
1222
+ if (body.kind === "listRuns") {
1223
+ const data = await this.gateway.listRuns({
1224
+ ...body.query,
1225
+ namespace: msg.tenant
1226
+ });
1227
+ return {
1228
+ requestId: msg.requestId,
1229
+ result: {
1230
+ ok: true,
1231
+ data
1232
+ }
1233
+ };
1234
+ }
1235
+ if (body.kind === "runFacets") {
1236
+ const data = await this.gateway.runFacets({
1237
+ ...body.query,
1238
+ namespace: msg.tenant
1239
+ });
1240
+ return {
1241
+ requestId: msg.requestId,
1242
+ result: {
1243
+ ok: true,
1244
+ data
1245
+ }
1246
+ };
1247
+ }
1248
+ if (body.kind === "runValueFacets") {
1249
+ const data = await this.gateway.runValueFacets(body.axis, {
1250
+ ...body.query,
1251
+ namespace: msg.tenant
1252
+ }, body.opts);
1253
+ return {
1254
+ requestId: msg.requestId,
1255
+ result: {
1256
+ ok: true,
1257
+ data
1258
+ }
1259
+ };
1260
+ }
1261
+ if (body.kind === "workerHealth") {
1262
+ const all = await this.gateway.workerHealth();
1263
+ const data = all.filter((h) => h.group.endsWith(`@${msg.tenant}`));
1264
+ return {
1265
+ requestId: msg.requestId,
1266
+ result: {
1267
+ ok: true,
1268
+ data
1269
+ }
1270
+ };
1271
+ }
1272
+ if (body.kind === "waitingFor") {
1273
+ const all = await this.gateway.waitingFor(body.runIds);
1274
+ const owned = await Promise.all(Object.entries(all).map(async ([runId, waiting]) => {
1275
+ const owner = this.gateway.getRun ? await this.gateway.getRun(runId) : (await this.gateway.getRunDetail(runId))?.run;
1276
+ return owner && owner.namespace === msg.tenant ? [
1277
+ runId,
1278
+ waiting
1279
+ ] : void 0;
1280
+ }));
1281
+ const data = {};
1282
+ for (const entry of owned) {
1283
+ if (entry) data[entry[0]] = entry[1];
1284
+ }
1285
+ return {
1286
+ requestId: msg.requestId,
1287
+ result: {
1288
+ ok: true,
1289
+ data
1290
+ }
1291
+ };
1292
+ }
1293
+ const detail = body.kind === "getRunDetail" || !this.gateway.getRun ? await this.gateway.getRunDetail(body.runId, body.kind === "getRunDetail" ? body.options : void 0) : void 0;
1294
+ const run = detail !== void 0 ? detail?.run ?? null : await this.gateway.getRun?.(body.runId);
1295
+ if (run && run.namespace !== msg.tenant) {
1296
+ return {
1297
+ requestId: msg.requestId,
1298
+ result: {
1299
+ ok: false,
1300
+ error: {
1301
+ message: "run belongs to another tenant",
1302
+ code: "cross-tenant"
1303
+ }
1304
+ }
1305
+ };
1306
+ }
1307
+ if (body.kind === "getRunDetail") {
1308
+ return {
1309
+ requestId: msg.requestId,
1310
+ result: {
1311
+ ok: true,
1312
+ data: detail
1313
+ }
1314
+ };
1315
+ }
1316
+ if (body.kind === "getFanMembers") {
1317
+ const data = run ? await this.gateway.getFanMembers?.(body.runId, body.group, body.query) ?? null : null;
1318
+ return {
1319
+ requestId: msg.requestId,
1320
+ result: {
1321
+ ok: true,
1322
+ data
1323
+ }
1324
+ };
1325
+ }
1326
+ try {
1327
+ const data = await this.callVerb(body);
1328
+ return {
1329
+ requestId: msg.requestId,
1330
+ result: {
1331
+ ok: true,
1332
+ data
1333
+ }
1334
+ };
1335
+ } catch (err) {
1336
+ return {
1337
+ requestId: msg.requestId,
1338
+ result: {
1339
+ ok: false,
1340
+ error: {
1341
+ message: err instanceof Error ? err.message : String(err)
1342
+ }
1343
+ }
1344
+ };
1345
+ }
1346
+ }
1347
+ callVerb(body) {
1348
+ switch (body.kind) {
1349
+ case "cancel":
1350
+ return this.gateway.cancel(body.runId, body.opts);
1351
+ case "retry":
1352
+ return this.gateway.retry(body.runId);
1353
+ case "continue":
1354
+ return this.gateway.continue(body.runId);
1355
+ case "retryWithInput":
1356
+ return this.gateway.retryWithInput(body.runId, body.input);
1357
+ case "redispatch":
1358
+ return this.gateway.redispatchPending(body.runId);
1359
+ }
1360
+ }
1361
+ };
1362
+
1363
+ // src/proxy-run-gateway.ts
1085
1364
  function _ts_decorate6(decorators, target, key, desc) {
1086
1365
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1087
1366
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -1102,6 +1381,15 @@ function _ts_metadata6(metadataKey, metadataValue) {
1102
1381
  }
1103
1382
  }
1104
1383
  __name(_ts_metadata6, "_ts_metadata");
1384
+ var UnsupportedRunRequestError = class UnsupportedRunRequestError2 extends Error {
1385
+ static {
1386
+ __name(this, "UnsupportedRunRequestError");
1387
+ }
1388
+ };
1389
+ function isUnsupported(err) {
1390
+ return err instanceof UnsupportedRunRequestError;
1391
+ }
1392
+ __name(isUnsupported, "isUnsupported");
1105
1393
  var ProxyRunGateway = class {
1106
1394
  static {
1107
1395
  __name(this, "ProxyRunGateway");
@@ -1109,11 +1397,18 @@ var ProxyRunGateway = class {
1109
1397
  transport;
1110
1398
  tenant;
1111
1399
  timeoutMs;
1400
+ capabilityTtlMs;
1112
1401
  pending = /* @__PURE__ */ new Map();
1113
- constructor(transport, tenant, timeoutMs = 1e4) {
1402
+ /** Verb → when to ask the control plane for it again, after it answered that it does not know it.
1403
+ * During a rolling upgrade the control plane is several pods of mixed versions behind one queue,
1404
+ * and a reply does not say which pod sent it, so the whole control plane is assumed old until the
1405
+ * entry expires. */
1406
+ unsupportedUntil = /* @__PURE__ */ new Map();
1407
+ constructor(transport, tenant, timeoutMs = 1e4, capabilityTtlMs = 6e4) {
1114
1408
  this.transport = transport;
1115
1409
  this.tenant = tenant;
1116
1410
  this.timeoutMs = timeoutMs;
1411
+ this.capabilityTtlMs = capabilityTtlMs;
1117
1412
  this.transport.onRunReply?.((reply) => this.handleReply(reply));
1118
1413
  }
1119
1414
  handleReply(reply) {
@@ -1123,6 +1418,8 @@ var ProxyRunGateway = class {
1123
1418
  this.pending.delete(reply.requestId);
1124
1419
  if (reply.result.ok) {
1125
1420
  pending.resolve(reply.result.data);
1421
+ } else if (reply.result.error.code === UNSUPPORTED_RUN_REQUEST) {
1422
+ pending.reject(new UnsupportedRunRequestError(reply.result.error.message));
1126
1423
  } else {
1127
1424
  pending.reject(new Error(reply.result.error.message));
1128
1425
  }
@@ -1158,20 +1455,59 @@ var ProxyRunGateway = class {
1158
1455
  tenant: this.tenant
1159
1456
  };
1160
1457
  }
1161
- getRunDetail(runId, options) {
1162
- return this.request({
1458
+ /**
1459
+ * A control plane that predates {@link RunDetailOptions} ignores them and sends the full detail;
1460
+ * a summarized detail always carries `fans`, so its absence means the summary is made here.
1461
+ */
1462
+ async getRunDetail(runId, options) {
1463
+ const detail = await this.request(options === void 0 ? {
1464
+ kind: "getRunDetail",
1465
+ runId
1466
+ } : {
1163
1467
  kind: "getRunDetail",
1164
1468
  runId,
1165
1469
  options
1166
1470
  });
1471
+ const over = options?.summarizeFansOver;
1472
+ if (over === void 0 || !detail || detail.fans !== void 0) return detail;
1473
+ const { timeline, fans } = (0, import_nestjs_durable_core9.summarizeTimeline)(detail.timeline, over);
1474
+ const ids = (0, import_nestjs_durable_core9.childIdsOf)(detail.timeline);
1475
+ return {
1476
+ ...detail,
1477
+ timeline,
1478
+ children: ids.slice(0, import_nestjs_durable_core9.SUMMARY_CHILD_LIMIT),
1479
+ fans,
1480
+ childCount: ids.length
1481
+ };
1167
1482
  }
1168
- getFanMembers(runId, group, query) {
1169
- return this.request({
1170
- kind: "getFanMembers",
1171
- runId,
1172
- group,
1173
- query
1483
+ /** Paged from the full detail when the control plane is too old to page a fan itself. */
1484
+ async getFanMembers(runId, group, query) {
1485
+ if (!this.knownUnsupported("getFanMembers")) {
1486
+ try {
1487
+ const page = await this.request({
1488
+ kind: "getFanMembers",
1489
+ runId,
1490
+ group,
1491
+ query
1492
+ });
1493
+ if (page !== void 0) return page;
1494
+ } catch (err) {
1495
+ if (!isUnsupported(err)) throw err;
1496
+ }
1497
+ this.unsupportedUntil.set("getFanMembers", Date.now() + this.capabilityTtlMs);
1498
+ }
1499
+ const detail = await this.request({
1500
+ kind: "getRunDetail",
1501
+ runId
1174
1502
  });
1503
+ return detail ? (0, import_nestjs_durable_core9.pageFan)(detail.timeline, group, query) : null;
1504
+ }
1505
+ knownUnsupported(kind) {
1506
+ const until = this.unsupportedUntil.get(kind);
1507
+ if (until === void 0) return false;
1508
+ if (Date.now() < until) return true;
1509
+ this.unsupportedUntil.delete(kind);
1510
+ return false;
1175
1511
  }
1176
1512
  /** The control plane's `StoreRunGateway` resolves each run's `waiting` descriptor; the reply carries
1177
1513
  * it through as plain JSON, so a tenant's list rows name the wait too. */
@@ -1261,12 +1597,13 @@ ProxyRunGateway = _ts_decorate6([
1261
1597
  _ts_metadata6("design:paramtypes", [
1262
1598
  typeof Transport === "undefined" ? Object : Transport,
1263
1599
  String,
1600
+ void 0,
1264
1601
  void 0
1265
1602
  ])
1266
1603
  ], ProxyRunGateway);
1267
1604
 
1268
1605
  // src/retention-poller.ts
1269
- var import_nestjs_durable_core8 = require("@dudousxd/nestjs-durable-core");
1606
+ var import_nestjs_durable_core10 = require("@dudousxd/nestjs-durable-core");
1270
1607
  var import_common7 = require("@nestjs/common");
1271
1608
 
1272
1609
  // src/settle-within.ts
@@ -1332,10 +1669,10 @@ function validateRetention(retention) {
1332
1669
  if (policy.maxAge == null && policy.maxCount == null) {
1333
1670
  throw new Error("durable retention: each policy must set maxAge and/or maxCount");
1334
1671
  }
1335
- if (policy.maxAge != null) (0, import_nestjs_durable_core8.parseDuration)(policy.maxAge);
1672
+ if (policy.maxAge != null) (0, import_nestjs_durable_core10.parseDuration)(policy.maxAge);
1336
1673
  for (const status of policy.statuses) {
1337
- if (!import_nestjs_durable_core8.TERMINAL_RUN_STATUSES.includes(status)) {
1338
- throw new Error(`durable retention: status "${status}" is not terminal; only ${import_nestjs_durable_core8.TERMINAL_RUN_STATUSES.join(", ")} can be pruned`);
1674
+ if (!import_nestjs_durable_core10.TERMINAL_RUN_STATUSES.includes(status)) {
1675
+ throw new Error(`durable retention: status "${status}" is not terminal; only ${import_nestjs_durable_core10.TERMINAL_RUN_STATUSES.join(", ")} can be pruned`);
1339
1676
  }
1340
1677
  const key = `${scopeKey}|${status}`;
1341
1678
  if (seen.has(key)) {
@@ -1387,7 +1724,7 @@ var RetentionPoller = class {
1387
1724
  return;
1388
1725
  }
1389
1726
  await this.sweep();
1390
- const intervalMs = retention.sweepInterval != null ? (0, import_nestjs_durable_core8.parseDuration)(retention.sweepInterval) : DEFAULT_SWEEP_INTERVAL_MS;
1727
+ const intervalMs = retention.sweepInterval != null ? (0, import_nestjs_durable_core10.parseDuration)(retention.sweepInterval) : DEFAULT_SWEEP_INTERVAL_MS;
1391
1728
  if (intervalMs > 0) {
1392
1729
  this.timer = setInterval(() => void this.sweep(), intervalMs);
1393
1730
  this.timer.unref?.();
@@ -1449,8 +1786,8 @@ var RetentionPoller = class {
1449
1786
  };
1450
1787
  RetentionPoller = _ts_decorate7([
1451
1788
  (0, import_common7.Injectable)(),
1452
- _ts_param4(0, (0, import_common7.Inject)(import_nestjs_durable_core8.STATE_STORE_CANONICAL)),
1453
- _ts_param4(1, (0, import_common7.Inject)(import_nestjs_durable_core8.DURABLE_OPTIONS_CANONICAL)),
1789
+ _ts_param4(0, (0, import_common7.Inject)(import_nestjs_durable_core10.STATE_STORE_CANONICAL)),
1790
+ _ts_param4(1, (0, import_common7.Inject)(import_nestjs_durable_core10.DURABLE_OPTIONS_CANONICAL)),
1454
1791
  _ts_metadata7("design:type", Function),
1455
1792
  _ts_metadata7("design:paramtypes", [
1456
1793
  Object,
@@ -1458,170 +1795,8 @@ RetentionPoller = _ts_decorate7([
1458
1795
  ])
1459
1796
  ], RetentionPoller);
1460
1797
 
1461
- // src/run-request-responder.ts
1462
- var RunRequestResponder = class {
1463
- static {
1464
- __name(this, "RunRequestResponder");
1465
- }
1466
- transport;
1467
- gateway;
1468
- constructor(transport, gateway) {
1469
- this.transport = transport;
1470
- this.gateway = gateway;
1471
- }
1472
- /** Register the consumer on the transport. Each request is answered independently; a handler
1473
- * failure never throws back into the transport (errors are captured into an error reply). */
1474
- start() {
1475
- this.transport.onRunRequest(async (msg) => {
1476
- const reply = await this.handle(msg);
1477
- await this.transport.publishRunReply(reply);
1478
- });
1479
- }
1480
- async handle(msg) {
1481
- const { body } = msg;
1482
- if (body.kind === "listRuns") {
1483
- const data = await this.gateway.listRuns({
1484
- ...body.query,
1485
- namespace: msg.tenant
1486
- });
1487
- return {
1488
- requestId: msg.requestId,
1489
- result: {
1490
- ok: true,
1491
- data
1492
- }
1493
- };
1494
- }
1495
- if (body.kind === "runFacets") {
1496
- const data = await this.gateway.runFacets({
1497
- ...body.query,
1498
- namespace: msg.tenant
1499
- });
1500
- return {
1501
- requestId: msg.requestId,
1502
- result: {
1503
- ok: true,
1504
- data
1505
- }
1506
- };
1507
- }
1508
- if (body.kind === "runValueFacets") {
1509
- const data = await this.gateway.runValueFacets(body.axis, {
1510
- ...body.query,
1511
- namespace: msg.tenant
1512
- }, body.opts);
1513
- return {
1514
- requestId: msg.requestId,
1515
- result: {
1516
- ok: true,
1517
- data
1518
- }
1519
- };
1520
- }
1521
- if (body.kind === "workerHealth") {
1522
- const all = await this.gateway.workerHealth();
1523
- const data = all.filter((h) => h.group.endsWith(`@${msg.tenant}`));
1524
- return {
1525
- requestId: msg.requestId,
1526
- result: {
1527
- ok: true,
1528
- data
1529
- }
1530
- };
1531
- }
1532
- if (body.kind === "waitingFor") {
1533
- const all = await this.gateway.waitingFor(body.runIds);
1534
- const owned = await Promise.all(Object.entries(all).map(async ([runId, waiting]) => {
1535
- const owner = this.gateway.getRun ? await this.gateway.getRun(runId) : (await this.gateway.getRunDetail(runId))?.run;
1536
- return owner && owner.namespace === msg.tenant ? [
1537
- runId,
1538
- waiting
1539
- ] : void 0;
1540
- }));
1541
- const data = {};
1542
- for (const entry of owned) {
1543
- if (entry) data[entry[0]] = entry[1];
1544
- }
1545
- return {
1546
- requestId: msg.requestId,
1547
- result: {
1548
- ok: true,
1549
- data
1550
- }
1551
- };
1552
- }
1553
- const detail = body.kind === "getRunDetail" || !this.gateway.getRun ? await this.gateway.getRunDetail(body.runId, body.kind === "getRunDetail" ? body.options : void 0) : void 0;
1554
- const run = detail !== void 0 ? detail?.run ?? null : await this.gateway.getRun?.(body.runId);
1555
- if (run && run.namespace !== msg.tenant) {
1556
- return {
1557
- requestId: msg.requestId,
1558
- result: {
1559
- ok: false,
1560
- error: {
1561
- message: "run belongs to another tenant",
1562
- code: "cross-tenant"
1563
- }
1564
- }
1565
- };
1566
- }
1567
- if (body.kind === "getRunDetail") {
1568
- return {
1569
- requestId: msg.requestId,
1570
- result: {
1571
- ok: true,
1572
- data: detail
1573
- }
1574
- };
1575
- }
1576
- if (body.kind === "getFanMembers") {
1577
- const data = run ? await this.gateway.getFanMembers?.(body.runId, body.group, body.query) ?? null : null;
1578
- return {
1579
- requestId: msg.requestId,
1580
- result: {
1581
- ok: true,
1582
- data
1583
- }
1584
- };
1585
- }
1586
- try {
1587
- const data = await this.callVerb(body);
1588
- return {
1589
- requestId: msg.requestId,
1590
- result: {
1591
- ok: true,
1592
- data
1593
- }
1594
- };
1595
- } catch (err) {
1596
- return {
1597
- requestId: msg.requestId,
1598
- result: {
1599
- ok: false,
1600
- error: {
1601
- message: err instanceof Error ? err.message : String(err)
1602
- }
1603
- }
1604
- };
1605
- }
1606
- }
1607
- callVerb(body) {
1608
- switch (body.kind) {
1609
- case "cancel":
1610
- return this.gateway.cancel(body.runId, body.opts);
1611
- case "retry":
1612
- return this.gateway.retry(body.runId);
1613
- case "continue":
1614
- return this.gateway.continue(body.runId);
1615
- case "retryWithInput":
1616
- return this.gateway.retryWithInput(body.runId, body.input);
1617
- case "redispatch":
1618
- return this.gateway.redispatchPending(body.runId);
1619
- }
1620
- }
1621
- };
1622
-
1623
1798
  // src/store-run-gateway.ts
1624
- var import_nestjs_durable_core9 = require("@dudousxd/nestjs-durable-core");
1799
+ var import_nestjs_durable_core11 = require("@dudousxd/nestjs-durable-core");
1625
1800
  var import_common8 = require("@nestjs/common");
1626
1801
  function _ts_decorate8(decorators, target, key, desc) {
1627
1802
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -1679,13 +1854,31 @@ var StoreRunGateway = class {
1679
1854
  children
1680
1855
  };
1681
1856
  }
1857
+ if ((0, import_nestjs_durable_core11.aggregatesCheckpoints)(this.store)) {
1858
+ const stats = await this.store.checkpointStats(runId);
1859
+ const etag = (0, import_nestjs_durable_core11.runDetailEtag)(run, stats, over);
1860
+ if ((0, import_nestjs_durable_core11.etagMatches)(options?.ifNoneMatch, etag)) {
1861
+ return {
1862
+ run,
1863
+ timeline: [],
1864
+ children: [],
1865
+ notModified: true,
1866
+ etag
1867
+ };
1868
+ }
1869
+ return {
1870
+ run,
1871
+ ...await (0, import_nestjs_durable_core11.summarizeRunFromStore)(this.store, runId, over, stats),
1872
+ etag
1873
+ };
1874
+ }
1682
1875
  const full = await this.store.listCheckpoints(runId);
1683
- const { timeline, fans } = (0, import_nestjs_durable_core9.summarizeTimeline)(full, over);
1684
- const ids = (0, import_nestjs_durable_core9.childIdsOf)(full);
1876
+ const { timeline, fans } = (0, import_nestjs_durable_core11.summarizeTimeline)(full, over);
1877
+ const ids = (0, import_nestjs_durable_core11.childIdsOf)(full);
1685
1878
  return {
1686
1879
  run,
1687
1880
  timeline,
1688
- children: ids.slice(0, import_nestjs_durable_core9.SUMMARY_CHILD_LIMIT),
1881
+ children: ids.slice(0, import_nestjs_durable_core11.SUMMARY_CHILD_LIMIT),
1689
1882
  fans,
1690
1883
  childCount: ids.length
1691
1884
  };
@@ -1695,13 +1888,31 @@ var StoreRunGateway = class {
1695
1888
  }
1696
1889
  async getFanMembers(runId, group, query) {
1697
1890
  if (!await this.store.getRun(runId)) return null;
1698
- return (0, import_nestjs_durable_core9.pageFan)(await this.store.listCheckpoints(runId), group, query);
1891
+ if ((0, import_nestjs_durable_core11.aggregatesCheckpoints)(this.store)) {
1892
+ const stats = await this.store.checkpointStats(runId, {
1893
+ group
1894
+ });
1895
+ const etag = (0, import_nestjs_durable_core11.fanPageEtag)(group, stats, query);
1896
+ if ((0, import_nestjs_durable_core11.etagMatches)(query.ifNoneMatch, etag)) {
1897
+ return {
1898
+ items: [],
1899
+ total: 0,
1900
+ notModified: true,
1901
+ etag
1902
+ };
1903
+ }
1904
+ return {
1905
+ ...await (0, import_nestjs_durable_core11.pageFanFromStore)(this.store, runId, group, query, stats),
1906
+ etag
1907
+ };
1908
+ }
1909
+ return (0, import_nestjs_durable_core11.pageFan)(await this.store.listCheckpoints(runId), group, query);
1699
1910
  }
1700
1911
  async listRuns(query) {
1701
1912
  const runs = await this.store.listRuns(query);
1702
- const waiterByRun = (0, import_nestjs_durable_core9.indexWaitersByRun)(await (0, import_nestjs_durable_core9.listSignalWaitersOfRuns)(this.store, runs.filter((run) => run.status === "suspended").map((run) => run.id)));
1913
+ const waiterByRun = (0, import_nestjs_durable_core11.indexWaitersByRun)(await (0, import_nestjs_durable_core11.listSignalWaitersOfRuns)(this.store, runs.filter((run) => run.status === "suspended").map((run) => run.id)));
1703
1914
  return runs.map((run) => {
1704
- const waiting = (0, import_nestjs_durable_core9.resolveRunWaiting)(run, waiterByRun);
1915
+ const waiting = (0, import_nestjs_durable_core11.resolveRunWaiting)(run, waiterByRun);
1705
1916
  return waiting ? {
1706
1917
  ...run,
1707
1918
  waiting
@@ -1717,7 +1928,7 @@ var StoreRunGateway = class {
1717
1928
  async runFacets(query) {
1718
1929
  if (this.store.runFacets) return this.store.runFacets(query);
1719
1930
  const runs = await this.store.listRuns(query);
1720
- return (0, import_nestjs_durable_core9.mergeRunFacetRows)(runs.map((r) => ({
1931
+ return (0, import_nestjs_durable_core11.mergeRunFacetRows)(runs.map((r) => ({
1721
1932
  status: r.status,
1722
1933
  origin: r.origin,
1723
1934
  count: 1
@@ -1752,13 +1963,13 @@ var StoreRunGateway = class {
1752
1963
  "suspended"
1753
1964
  ]
1754
1965
  }),
1755
- (0, import_nestjs_durable_core9.listSignalWaitersOfRuns)(this.store, runIds)
1966
+ (0, import_nestjs_durable_core11.listSignalWaitersOfRuns)(this.store, runIds)
1756
1967
  ]);
1757
- const waiterByRun = (0, import_nestjs_durable_core9.indexWaitersByRun)(waiters);
1968
+ const waiterByRun = (0, import_nestjs_durable_core11.indexWaitersByRun)(waiters);
1758
1969
  const result = {};
1759
1970
  for (const run of suspended) {
1760
1971
  if (!idSet.has(run.id)) continue;
1761
- const waiting = (0, import_nestjs_durable_core9.resolveRunWaiting)(run, waiterByRun);
1972
+ const waiting = (0, import_nestjs_durable_core11.resolveRunWaiting)(run, waiterByRun);
1762
1973
  if (waiting) result[run.id] = waiting;
1763
1974
  }
1764
1975
  return result;
@@ -1792,11 +2003,11 @@ var StoreRunGateway = class {
1792
2003
  };
1793
2004
  StoreRunGateway = _ts_decorate8([
1794
2005
  (0, import_common8.Injectable)(),
1795
- _ts_param5(0, (0, import_common8.Inject)(import_nestjs_durable_core9.STATE_STORE_CANONICAL)),
2006
+ _ts_param5(0, (0, import_common8.Inject)(import_nestjs_durable_core11.STATE_STORE_CANONICAL)),
1796
2007
  _ts_metadata8("design:type", Function),
1797
2008
  _ts_metadata8("design:paramtypes", [
1798
2009
  typeof StateStore === "undefined" ? Object : StateStore,
1799
- typeof import_nestjs_durable_core9.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core9.WorkflowEngine
2010
+ typeof import_nestjs_durable_core11.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core11.WorkflowEngine
1800
2011
  ])
1801
2012
  ], StoreRunGateway);
1802
2013
 
@@ -1842,7 +2053,7 @@ var TenantEventRepublisher = class {
1842
2053
  };
1843
2054
 
1844
2055
  // src/timer-poller.ts
1845
- var import_nestjs_durable_core10 = require("@dudousxd/nestjs-durable-core");
2056
+ var import_nestjs_durable_core12 = require("@dudousxd/nestjs-durable-core");
1846
2057
  var import_common9 = require("@nestjs/common");
1847
2058
  function _ts_decorate9(decorators, target, key, desc) {
1848
2059
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -1954,7 +2165,7 @@ var TimerPoller = class {
1954
2165
  await this.sweep("sweepTimeouts", () => this.engine.sweepTimeouts());
1955
2166
  const schedules = this.options.schedules;
1956
2167
  if (schedules && schedules.length > 0) {
1957
- await this.sweep("schedules", () => (0, import_nestjs_durable_core10.runSchedules)(this.engine, schedules, Date.now()));
2168
+ await this.sweep("schedules", () => (0, import_nestjs_durable_core12.runSchedules)(this.engine, schedules, Date.now()));
1958
2169
  }
1959
2170
  if (this.options.persistedSchedules) {
1960
2171
  await this.sweep("persistedSchedules", () => this.engine.schedules.tick());
@@ -1972,21 +2183,21 @@ var TimerPoller = class {
1972
2183
  };
1973
2184
  TimerPoller = _ts_decorate9([
1974
2185
  (0, import_common9.Injectable)(),
1975
- _ts_param6(1, (0, import_common9.Inject)(import_nestjs_durable_core10.DURABLE_OPTIONS_CANONICAL)),
2186
+ _ts_param6(1, (0, import_common9.Inject)(import_nestjs_durable_core12.DURABLE_OPTIONS_CANONICAL)),
1976
2187
  _ts_metadata9("design:type", Function),
1977
2188
  _ts_metadata9("design:paramtypes", [
1978
- typeof import_nestjs_durable_core10.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core10.WorkflowEngine,
2189
+ typeof import_nestjs_durable_core12.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core12.WorkflowEngine,
1979
2190
  typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions
1980
2191
  ])
1981
2192
  ], TimerPoller);
1982
2193
 
1983
2194
  // src/tokens.ts
1984
- var import_nestjs_durable_core11 = require("@dudousxd/nestjs-durable-core");
2195
+ var import_nestjs_durable_core13 = require("@dudousxd/nestjs-durable-core");
1985
2196
  var CONTEXT_ACCESSOR = Symbol.for("@dudousxd/nestjs-context:accessor");
1986
- var RUN_GATEWAY = import_nestjs_durable_core11.RunGateway;
2197
+ var RUN_GATEWAY = import_nestjs_durable_core13.RunGateway;
1987
2198
 
1988
2199
  // src/workflow.registrar.ts
1989
- var import_nestjs_durable_core12 = require("@dudousxd/nestjs-durable-core");
2200
+ var import_nestjs_durable_core14 = require("@dudousxd/nestjs-durable-core");
1990
2201
  var import_common10 = require("@nestjs/common");
1991
2202
  var import_core4 = require("@nestjs/core");
1992
2203
 
@@ -2056,6 +2267,7 @@ function _ts_param7(paramIndex, decorator) {
2056
2267
  };
2057
2268
  }
2058
2269
  __name(_ts_param7, "_ts_param");
2270
+ var UNSERVED_ROUTES_RECHECK_MS = 3e4;
2059
2271
  var WorkflowRegistrar = class {
2060
2272
  static {
2061
2273
  __name(this, "WorkflowRegistrar");
@@ -2119,13 +2331,19 @@ var WorkflowRegistrar = class {
2119
2331
  const validateInput = meta.validateInput ?? (meta.inputSchema ? classValidatorInput(meta.inputSchema) : void 0);
2120
2332
  const eventBatch = meta.debounce ? {
2121
2333
  mode: "debounce",
2122
- windowMs: (0, import_nestjs_durable_core12.parseDuration)(meta.debounce)
2334
+ windowMs: (0, import_nestjs_durable_core14.parseDuration)(meta.debounce)
2123
2335
  } : meta.batch ? {
2124
2336
  mode: "batch",
2125
2337
  maxSize: meta.batch.maxSize,
2126
- windowMs: (0, import_nestjs_durable_core12.parseDuration)(meta.batch.within)
2338
+ windowMs: (0, import_nestjs_durable_core14.parseDuration)(meta.batch.within)
2127
2339
  } : void 0;
2128
2340
  const workflowCtor = workflow.constructor;
2341
+ const onError = onErrorHandlersOf(meta, workflow, this.metadataScanner);
2342
+ for (const [name, fn] of onError.handlers) {
2343
+ this.engine.register(name, meta.version, fn, {
2344
+ origin
2345
+ });
2346
+ }
2129
2347
  this.engine.register(meta.name, meta.version, (ctx, input) => workflow.run(ctx, input), {
2130
2348
  // Stamped onto every run this workflow starts (see `WorkflowRun.origin`). Derived from the
2131
2349
  // class's declaring file, so a lib gets attributed without opting in; `undefined` when it
@@ -2140,6 +2358,7 @@ var WorkflowRegistrar = class {
2140
2358
  searchAttributesSchema: meta.searchAttributes,
2141
2359
  onEvent: getOnEvents(meta, workflowCtor),
2142
2360
  eventBatch,
2361
+ onError: onError.routes,
2143
2362
  // Uniform dispatch (opt-in): when an in-app worker is configured, register the body GROUP-SERVED
2144
2363
  // so the engine dispatches its turns over the transport instead of running it inline; the
2145
2364
  // co-located worker consumer (Task 5: one queue PER REGISTERED NAME) replays the same body.
@@ -2150,11 +2369,11 @@ var WorkflowRegistrar = class {
2150
2369
  // so a turn dispatched under the wrong token would never be consumed. Absent → the inline fast
2151
2370
  // path (unchanged).
2152
2371
  ...this.inAppWorker ? {
2153
- group: (0, import_nestjs_durable_core12.tenantGroup)((0, import_nestjs_durable_core12.sanitizeQueueToken)(meta.name), this.inAppWorker.partition),
2154
- executor: new import_nestjs_durable_core12.RemoteWorkflowExecutor(this.inAppWorker.transport, meta.name, this.inAppWorker.partition)
2372
+ group: (0, import_nestjs_durable_core14.tenantGroup)((0, import_nestjs_durable_core14.sanitizeQueueToken)(meta.name), this.inAppWorker.partition),
2373
+ executor: new import_nestjs_durable_core14.RemoteWorkflowExecutor(this.inAppWorker.transport, meta.name, this.inAppWorker.partition)
2155
2374
  } : {}
2156
2375
  });
2157
- (0, import_nestjs_durable_core12.bindWorkflowClass)(workflowCtor, {
2376
+ (0, import_nestjs_durable_core14.bindWorkflowClass)(workflowCtor, {
2158
2377
  start: /* @__PURE__ */ __name((name, input, runId, opts) => this.engine.start(name, input, runId, opts), "start"),
2159
2378
  waitForRun: /* @__PURE__ */ __name((runId, opts) => this.engine.waitForRun(runId, opts), "waitForRun")
2160
2379
  });
@@ -2169,10 +2388,11 @@ var WorkflowRegistrar = class {
2169
2388
  });
2170
2389
  deadLetterByWorkflow.set(meta.name, dlqName);
2171
2390
  } else if (meta.deadLetterWorkflow) {
2172
- deadLetterByWorkflow.set(meta.name, (0, import_nestjs_durable_core12.workflowName)(meta.deadLetterWorkflow));
2391
+ deadLetterByWorkflow.set(meta.name, (0, import_nestjs_durable_core14.workflowName)(meta.deadLetterWorkflow));
2173
2392
  }
2174
2393
  });
2175
2394
  this.reportUnattributed(unattributed);
2395
+ void this.reportUnservedOnErrorRoutes();
2176
2396
  this.installDeadLetterRouting(deadLetterByWorkflow);
2177
2397
  }
2178
2398
  /**
@@ -2185,6 +2405,20 @@ var WorkflowRegistrar = class {
2185
2405
  if (names.length === 0) return;
2186
2406
  console.warn(`[nestjs-durable] could not derive an origin (declaring package) for ${names.length} workflow(s): ${names.join(", ")}. Their runs carry no origin and will not match an origin filter.`);
2187
2407
  }
2408
+ /**
2409
+ * Says, once after boot, which onError routes name a handler workflow nothing can run, so a typo is
2410
+ * caught before the first failure goes nowhere. Routes unserved at boot are checked again after
2411
+ * {@link UNSERVED_ROUTES_RECHECK_MS}, so a handler whose workers start after this process is not
2412
+ * reported.
2413
+ */
2414
+ async reportUnservedOnErrorRoutes(recheckMs = UNSERVED_ROUTES_RECHECK_MS) {
2415
+ if ((await this.engine.unservedOnErrorRoutes().catch(() => [])).length === 0) return;
2416
+ await new Promise((resolve) => setTimeout(resolve, recheckMs).unref());
2417
+ const unserved = await this.engine.unservedOnErrorRoutes().catch(() => []);
2418
+ if (unserved.length === 0) return;
2419
+ const list = unserved.map(({ workflow, route }) => `${workflow} \u2192 ${route.workflow} (code ${route.code ?? "*"})`).join(", ");
2420
+ console.warn(`[nestjs-durable] ${unserved.length} onError route(s) name a handler workflow that is not registered here and has no live worker: ${list}.`);
2421
+ }
2188
2422
  /** Returns the instance's `@DeadLetter()` method bound to the instance, or undefined if none. */
2189
2423
  findDeadLetterHandler(instance) {
2190
2424
  const prototype = Object.getPrototypeOf(instance);
@@ -2202,7 +2436,7 @@ var WorkflowRegistrar = class {
2202
2436
  * a `dlq:<runId>` id, so re-recovery never double-dispatches.
2203
2437
  */
2204
2438
  installDeadLetterRouting(byWorkflow) {
2205
- const fallback = this.options.deadLetterWorkflow ? (0, import_nestjs_durable_core12.workflowName)(this.options.deadLetterWorkflow) : void 0;
2439
+ const fallback = this.options.deadLetterWorkflow ? (0, import_nestjs_durable_core14.workflowName)(this.options.deadLetterWorkflow) : void 0;
2206
2440
  if (byWorkflow.size === 0 && !fallback) return;
2207
2441
  this.engine.onDead((run) => {
2208
2442
  const target = byWorkflow.get(run.workflow) ?? fallback;
@@ -2227,14 +2461,14 @@ var WorkflowRegistrar = class {
2227
2461
  };
2228
2462
  WorkflowRegistrar = _ts_decorate10([
2229
2463
  (0, import_common10.Injectable)(),
2230
- _ts_param7(3, (0, import_common10.Inject)(import_nestjs_durable_core12.STATE_STORE_CANONICAL)),
2231
- _ts_param7(4, (0, import_common10.Inject)(import_nestjs_durable_core12.DURABLE_OPTIONS_CANONICAL)),
2464
+ _ts_param7(3, (0, import_common10.Inject)(import_nestjs_durable_core14.STATE_STORE_CANONICAL)),
2465
+ _ts_param7(4, (0, import_common10.Inject)(import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL)),
2232
2466
  _ts_param7(5, (0, import_common10.Inject)(IN_APP_WORKER_BINDING)),
2233
2467
  _ts_metadata10("design:type", Function),
2234
2468
  _ts_metadata10("design:paramtypes", [
2235
2469
  typeof import_core4.DiscoveryService === "undefined" ? Object : import_core4.DiscoveryService,
2236
2470
  typeof import_core4.MetadataScanner === "undefined" ? Object : import_core4.MetadataScanner,
2237
- typeof import_nestjs_durable_core12.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core12.WorkflowEngine,
2471
+ typeof import_nestjs_durable_core14.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core14.WorkflowEngine,
2238
2472
  Object,
2239
2473
  typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions,
2240
2474
  Object
@@ -2243,7 +2477,7 @@ WorkflowRegistrar = _ts_decorate10([
2243
2477
 
2244
2478
  // src/workflow.service.ts
2245
2479
  var import_node_crypto = require("crypto");
2246
- var import_nestjs_durable_core13 = require("@dudousxd/nestjs-durable-core");
2480
+ var import_nestjs_durable_core15 = require("@dudousxd/nestjs-durable-core");
2247
2481
  var import_common11 = require("@nestjs/common");
2248
2482
  function _ts_decorate11(decorators, target, key, desc) {
2249
2483
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2312,7 +2546,7 @@ WorkflowService = _ts_decorate11([
2312
2546
  (0, import_common11.Injectable)(),
2313
2547
  _ts_metadata11("design:type", Function),
2314
2548
  _ts_metadata11("design:paramtypes", [
2315
- typeof import_nestjs_durable_core13.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core13.WorkflowEngine
2549
+ typeof import_nestjs_durable_core15.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core15.WorkflowEngine
2316
2550
  ])
2317
2551
  ], WorkflowService);
2318
2552
 
@@ -2394,6 +2628,15 @@ function scopedStore(store, options) {
2394
2628
  });
2395
2629
  }
2396
2630
  __name(scopedStore, "scopedStore");
2631
+ function deferTransportConsumers(transport) {
2632
+ const deferrable = transport;
2633
+ if (typeof deferrable.deferConsumers === "function") {
2634
+ deferrable.deferConsumers();
2635
+ return;
2636
+ }
2637
+ console.warn(`[nestjs-durable] consumers: false \u2014 ${transport.constructor?.name ?? "this transport"} cannot defer its consumers and will keep consuming in this process`);
2638
+ }
2639
+ __name(deferTransportConsumers, "deferTransportConsumers");
2397
2640
  function assertValidRole(options) {
2398
2641
  const hasStore = options.store !== void 0;
2399
2642
  const hasConnection = options.connection !== void 0;
@@ -2515,14 +2758,14 @@ var RunGatewayBootstrap = class RunGatewayBootstrap2 {
2515
2758
  };
2516
2759
  RunGatewayBootstrap = _ts_decorate12([
2517
2760
  (0, import_common12.Injectable)(),
2518
- _ts_param8(1, (0, import_common12.Inject)(import_nestjs_durable_core14.TRANSPORT_CANONICAL)),
2519
- _ts_param8(3, (0, import_common12.Inject)(import_nestjs_durable_core14.STATE_STORE_CANONICAL)),
2520
- _ts_param8(4, (0, import_common12.Inject)(import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL)),
2761
+ _ts_param8(1, (0, import_common12.Inject)(import_nestjs_durable_core16.TRANSPORT_CANONICAL)),
2762
+ _ts_param8(3, (0, import_common12.Inject)(import_nestjs_durable_core16.STATE_STORE_CANONICAL)),
2763
+ _ts_param8(4, (0, import_common12.Inject)(import_nestjs_durable_core16.DURABLE_OPTIONS_CANONICAL)),
2521
2764
  _ts_metadata12("design:type", Function),
2522
2765
  _ts_metadata12("design:paramtypes", [
2523
- typeof import_nestjs_durable_core14.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core14.WorkflowEngine,
2766
+ typeof import_nestjs_durable_core16.WorkflowEngine === "undefined" ? Object : import_nestjs_durable_core16.WorkflowEngine,
2524
2767
  Object,
2525
- typeof import_nestjs_durable_core14.RunGateway === "undefined" ? Object : import_nestjs_durable_core14.RunGateway,
2768
+ typeof import_nestjs_durable_core16.RunGateway === "undefined" ? Object : import_nestjs_durable_core16.RunGateway,
2526
2769
  Object,
2527
2770
  typeof DurableModuleOptions === "undefined" ? Object : DurableModuleOptions
2528
2771
  ])
@@ -2534,13 +2777,13 @@ var DurableModule = class _DurableModule {
2534
2777
  static forRoot(options) {
2535
2778
  _DurableModule.assertValid(options);
2536
2779
  return _DurableModule.build({
2537
- provide: import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL,
2780
+ provide: import_nestjs_durable_core16.DURABLE_OPTIONS_CANONICAL,
2538
2781
  useValue: resolveTopology(options)
2539
2782
  });
2540
2783
  }
2541
2784
  static forRootAsync(options) {
2542
2785
  return _DurableModule.build({
2543
- provide: import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL,
2786
+ provide: import_nestjs_durable_core16.DURABLE_OPTIONS_CANONICAL,
2544
2787
  useFactory: /* @__PURE__ */ __name(async (...args) => {
2545
2788
  const resolved = await options.useFactory(...args);
2546
2789
  _DurableModule.assertValid(resolved);
@@ -2573,41 +2816,41 @@ var DurableModule = class _DurableModule {
2573
2816
  providers: [
2574
2817
  optionsProvider,
2575
2818
  {
2576
- provide: import_nestjs_durable_core14.STATE_STORE_CANONICAL,
2819
+ provide: import_nestjs_durable_core16.STATE_STORE_CANONICAL,
2577
2820
  useFactory: /* @__PURE__ */ __name((options) => options.store !== void 0 ? scopedStore(options.store, options) : null, "useFactory"),
2578
2821
  inject: [
2579
- import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL
2822
+ import_nestjs_durable_core16.DURABLE_OPTIONS_CANONICAL
2580
2823
  ]
2581
2824
  },
2582
2825
  {
2583
- provide: import_nestjs_durable_core14.TRANSPORT_CANONICAL,
2826
+ provide: import_nestjs_durable_core16.TRANSPORT_CANONICAL,
2584
2827
  // With a POOL (`transports`) and no singular `transport`, the canonical transport is the
2585
2828
  // pool's PRIMARY — the same one the engine dispatches on first. Leaving it null starved
2586
2829
  // the step registrar / in-app worker of a transport, so a pool-configured operator
2587
2830
  // registered NO step handlers and its own steps parked in `wait` with no consumer.
2588
2831
  useFactory: /* @__PURE__ */ __name((options) => options.transport ?? options.transports?.[0]?.transport ?? null, "useFactory"),
2589
2832
  inject: [
2590
- import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL
2833
+ import_nestjs_durable_core16.DURABLE_OPTIONS_CANONICAL
2591
2834
  ]
2592
2835
  },
2593
2836
  // Legacy back-compat aliases (deprecated tokens still resolve to the same instances):
2594
2837
  {
2595
- provide: import_nestjs_durable_core14.STATE_STORE,
2596
- useExisting: import_nestjs_durable_core14.STATE_STORE_CANONICAL
2838
+ provide: import_nestjs_durable_core16.STATE_STORE,
2839
+ useExisting: import_nestjs_durable_core16.STATE_STORE_CANONICAL
2597
2840
  },
2598
2841
  {
2599
- provide: import_nestjs_durable_core14.TRANSPORT,
2600
- useExisting: import_nestjs_durable_core14.TRANSPORT_CANONICAL
2842
+ provide: import_nestjs_durable_core16.TRANSPORT,
2843
+ useExisting: import_nestjs_durable_core16.TRANSPORT_CANONICAL
2601
2844
  },
2602
2845
  {
2603
- provide: import_nestjs_durable_core14.DURABLE_OPTIONS,
2604
- useExisting: import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL
2846
+ provide: import_nestjs_durable_core16.DURABLE_OPTIONS,
2847
+ useExisting: import_nestjs_durable_core16.DURABLE_OPTIONS_CANONICAL
2605
2848
  },
2606
2849
  {
2607
2850
  // Shared token, bound EXACTLY once: a real engine for the operator role, or a store-less
2608
2851
  // `DurableStartClient` facade for a thin worker (no `store`) — either way, `WorkflowService`
2609
2852
  // and app code call `engine.start(...)` unchanged.
2610
- provide: import_nestjs_durable_core14.WorkflowEngine,
2853
+ provide: import_nestjs_durable_core16.WorkflowEngine,
2611
2854
  useFactory: /* @__PURE__ */ __name(async (options, store, transport, moduleRef) => {
2612
2855
  if (options.store === void 0) {
2613
2856
  return new DurableStartClient(options);
@@ -2620,7 +2863,15 @@ var DurableModule = class _DurableModule {
2620
2863
  const context = options.context ?? (accessor ? () => carrierFromAccessor(accessor) : void 0);
2621
2864
  const runtime = accessor ? await resolveContextRuntime() : void 0;
2622
2865
  const rehydrate = runtime && ((carrier, fn) => carrier && Object.keys(carrier).length > 0 ? runtime.deserialize(carrier, fn) : fn());
2623
- const engine = new import_nestjs_durable_core14.WorkflowEngine({
2866
+ if (options.consumers === false) {
2867
+ for (const t of [
2868
+ transport,
2869
+ ...(options.transports ?? []).map((n) => n.transport)
2870
+ ]) {
2871
+ if (t) deferTransportConsumers(t);
2872
+ }
2873
+ }
2874
+ const engine = new import_nestjs_durable_core16.WorkflowEngine({
2624
2875
  store,
2625
2876
  transport: transport ?? void 0,
2626
2877
  transports: options.transports,
@@ -2658,9 +2909,9 @@ var DurableModule = class _DurableModule {
2658
2909
  return engine;
2659
2910
  }, "useFactory"),
2660
2911
  inject: [
2661
- import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL,
2662
- import_nestjs_durable_core14.STATE_STORE_CANONICAL,
2663
- import_nestjs_durable_core14.TRANSPORT_CANONICAL,
2912
+ import_nestjs_durable_core16.DURABLE_OPTIONS_CANONICAL,
2913
+ import_nestjs_durable_core16.STATE_STORE_CANONICAL,
2914
+ import_nestjs_durable_core16.TRANSPORT_CANONICAL,
2664
2915
  import_core5.ModuleRef
2665
2916
  ]
2666
2917
  },
@@ -2674,7 +2925,7 @@ var DurableModule = class _DurableModule {
2674
2925
  // or (for a thin worker, no `store`) a `ProxyRunGateway` over `transport` when given, else a
2675
2926
  // gateway whose every method rejects with a clear tenant error.
2676
2927
  {
2677
- provide: import_nestjs_durable_core14.RunGateway,
2928
+ provide: import_nestjs_durable_core16.RunGateway,
2678
2929
  useFactory: /* @__PURE__ */ __name((options, store, engine) => {
2679
2930
  if (options.store !== void 0) {
2680
2931
  if (!store) {
@@ -2685,9 +2936,9 @@ var DurableModule = class _DurableModule {
2685
2936
  return options.transport ? new ProxyRunGateway(options.transport, options.partition ?? "default", options.runGatewayTimeoutMs) : unavailableRunGateway();
2686
2937
  }, "useFactory"),
2687
2938
  inject: [
2688
- import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL,
2689
- import_nestjs_durable_core14.STATE_STORE_CANONICAL,
2690
- import_nestjs_durable_core14.WorkflowEngine
2939
+ import_nestjs_durable_core16.DURABLE_OPTIONS_CANONICAL,
2940
+ import_nestjs_durable_core16.STATE_STORE_CANONICAL,
2941
+ import_nestjs_durable_core16.WorkflowEngine
2691
2942
  ]
2692
2943
  },
2693
2944
  RunGatewayBootstrap,
@@ -2701,13 +2952,13 @@ var DurableModule = class _DurableModule {
2701
2952
  exports: [
2702
2953
  WorkflowService,
2703
2954
  EntityService,
2704
- import_nestjs_durable_core14.WorkflowEngine,
2705
- import_nestjs_durable_core14.STATE_STORE,
2706
- import_nestjs_durable_core14.STATE_STORE_CANONICAL,
2707
- import_nestjs_durable_core14.TRANSPORT,
2708
- import_nestjs_durable_core14.TRANSPORT_CANONICAL,
2709
- import_nestjs_durable_core14.DURABLE_OPTIONS_CANONICAL,
2710
- import_nestjs_durable_core14.RunGateway
2955
+ import_nestjs_durable_core16.WorkflowEngine,
2956
+ import_nestjs_durable_core16.STATE_STORE,
2957
+ import_nestjs_durable_core16.STATE_STORE_CANONICAL,
2958
+ import_nestjs_durable_core16.TRANSPORT,
2959
+ import_nestjs_durable_core16.TRANSPORT_CANONICAL,
2960
+ import_nestjs_durable_core16.DURABLE_OPTIONS_CANONICAL,
2961
+ import_nestjs_durable_core16.RunGateway
2711
2962
  ]
2712
2963
  };
2713
2964
  }
@@ -2717,7 +2968,7 @@ DurableModule = _ts_decorate12([
2717
2968
  ], DurableModule);
2718
2969
 
2719
2970
  // src/index.ts
2720
- var import_nestjs_durable_core15 = require("@dudousxd/nestjs-durable-core");
2971
+ var import_nestjs_durable_core17 = require("@dudousxd/nestjs-durable-core");
2721
2972
  // Annotate the CommonJS export names for ESM import in node:
2722
2973
  0 && (module.exports = {
2723
2974
  CONTEXT_ACCESSOR,
@@ -2738,9 +2989,11 @@ var import_nestjs_durable_core15 = require("@dudousxd/nestjs-durable-core");
2738
2989
  IN_APP_WORKER_RUNNERS,
2739
2990
  IN_APP_WORKER_RUNTIME,
2740
2991
  InAppWorkerBootstrap,
2992
+ ON_ERROR_METADATA,
2741
2993
  ON_EVENT_METADATA,
2742
2994
  On,
2743
2995
  OnDurableEvent,
2996
+ OnError,
2744
2997
  OnEvent,
2745
2998
  ProxyRunGateway,
2746
2999
  RUN_GATEWAY,
@@ -2755,6 +3008,7 @@ var import_nestjs_durable_core15 = require("@dudousxd/nestjs-durable-core");
2755
3008
  ThinStepRegistrar,
2756
3009
  ThinWorkerBootstrap,
2757
3010
  ThinWorkflowRegistrar,
3011
+ UNSUPPORTED_RUN_REQUEST,
2758
3012
  WORKFLOW_METADATA,
2759
3013
  Workflow,
2760
3014
  WorkflowEngine,
@@ -2770,6 +3024,7 @@ var import_nestjs_durable_core15 = require("@dudousxd/nestjs-durable-core");
2770
3024
  isDrivingOperator,
2771
3025
  isOperatorRole,
2772
3026
  isStepInterceptor,
3027
+ onErrorCodesOf,
2773
3028
  readSearchAttributes,
2774
3029
  thinWorkerProviders,
2775
3030
  unavailableRunGateway