@horizon-republic/nestjs-jetstream 2.9.0 → 2.9.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
@@ -7,11 +7,11 @@ var __export = (target, all) => {
7
7
  for (var name in all)
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
- var __copyProps = (to, from4, except, desc) => {
11
- if (from4 && typeof from4 === "object" || typeof from4 === "function") {
12
- for (let key of __getOwnPropNames(from4))
10
+ var __copyProps = (to, from2, except, desc) => {
11
+ if (from2 && typeof from2 === "object" || typeof from2 === "function") {
12
+ for (let key of __getOwnPropNames(from2))
13
13
  if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from4[key], enumerable: !(desc = __getOwnPropDesc(from4, key)) || desc.enumerable });
14
+ __defProp(to, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable });
15
15
  }
16
16
  return to;
17
17
  };
@@ -29,14 +29,23 @@ var __decorateParam = (index, decorator) => (target, key) => decorator(target, k
29
29
  // src/index.ts
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
+ DEFAULT_BROADCAST_CONSUMER_CONFIG: () => DEFAULT_BROADCAST_CONSUMER_CONFIG,
33
+ DEFAULT_BROADCAST_STREAM_CONFIG: () => DEFAULT_BROADCAST_STREAM_CONFIG,
34
+ DEFAULT_COMMAND_CONSUMER_CONFIG: () => DEFAULT_COMMAND_CONSUMER_CONFIG,
35
+ DEFAULT_COMMAND_STREAM_CONFIG: () => DEFAULT_COMMAND_STREAM_CONFIG,
36
+ DEFAULT_DLQ_STREAM_CONFIG: () => DEFAULT_DLQ_STREAM_CONFIG,
37
+ DEFAULT_EVENT_CONSUMER_CONFIG: () => DEFAULT_EVENT_CONSUMER_CONFIG,
38
+ DEFAULT_EVENT_STREAM_CONFIG: () => DEFAULT_EVENT_STREAM_CONFIG,
39
+ DEFAULT_JETSTREAM_RPC_TIMEOUT: () => DEFAULT_JETSTREAM_RPC_TIMEOUT,
32
40
  DEFAULT_METADATA_BUCKET: () => DEFAULT_METADATA_BUCKET,
33
41
  DEFAULT_METADATA_HISTORY: () => DEFAULT_METADATA_HISTORY,
34
42
  DEFAULT_METADATA_REPLICAS: () => DEFAULT_METADATA_REPLICAS,
35
43
  DEFAULT_METADATA_TTL: () => DEFAULT_METADATA_TTL,
36
- EventBus: () => EventBus,
44
+ DEFAULT_ORDERED_STREAM_CONFIG: () => DEFAULT_ORDERED_STREAM_CONFIG,
45
+ DEFAULT_RPC_TIMEOUT: () => DEFAULT_RPC_TIMEOUT,
46
+ DEFAULT_SHUTDOWN_TIMEOUT: () => DEFAULT_SHUTDOWN_TIMEOUT,
37
47
  JETSTREAM_CODEC: () => JETSTREAM_CODEC,
38
48
  JETSTREAM_CONNECTION: () => JETSTREAM_CONNECTION,
39
- JETSTREAM_EVENT_BUS: () => JETSTREAM_EVENT_BUS,
40
49
  JETSTREAM_OPTIONS: () => JETSTREAM_OPTIONS,
41
50
  JetstreamClient: () => JetstreamClient,
42
51
  JetstreamDlqHeader: () => JetstreamDlqHeader,
@@ -49,7 +58,10 @@ __export(index_exports, {
49
58
  JsonCodec: () => JsonCodec,
50
59
  MIN_METADATA_TTL: () => MIN_METADATA_TTL,
51
60
  MessageKind: () => MessageKind,
61
+ MsgpackCodec: () => MsgpackCodec,
62
+ NatsErrorCode: () => NatsErrorCode,
52
63
  PatternPrefix: () => PatternPrefix,
64
+ RESERVED_HEADERS: () => RESERVED_HEADERS,
53
65
  RpcContext: () => RpcContext,
54
66
  StreamKind: () => StreamKind,
55
67
  TransportEvent: () => TransportEvent,
@@ -438,6 +450,7 @@ var nanosToGoDuration = (nanos) => {
438
450
  };
439
451
 
440
452
  // src/client/jetstream.client.ts
453
+ var BROADCAST_SUBJECT_PREFIX = "broadcast.";
441
454
  var JetstreamClient = class extends import_microservices.ClientProxy {
442
455
  constructor(rootOptions, targetServiceName, connection, codec, eventBus) {
443
456
  super();
@@ -447,12 +460,33 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
447
460
  this.eventBus = eventBus;
448
461
  this.targetName = targetServiceName;
449
462
  this.callerName = internalName(this.rootOptions.name);
463
+ const targetInternal = internalName(targetServiceName);
464
+ this.eventSubjectPrefix = `${targetInternal}.${"ev" /* Event */}.`;
465
+ this.commandSubjectPrefix = `${targetInternal}.${"cmd" /* Command */}.`;
466
+ this.orderedSubjectPrefix = `${targetInternal}.${"ordered" /* Ordered */}.`;
467
+ this.isCoreMode = isCoreRpcMode(this.rootOptions.rpc);
468
+ this.defaultRpcTimeout = isJetStreamRpcMode(this.rootOptions.rpc) ? this.rootOptions.rpc?.timeout ?? DEFAULT_JETSTREAM_RPC_TIMEOUT : this.rootOptions.rpc?.timeout ?? DEFAULT_RPC_TIMEOUT;
450
469
  }
451
470
  logger = new import_common.Logger("Jetstream:Client");
452
471
  /** Target service name this client sends messages to. */
453
472
  targetName;
454
473
  /** Pre-cached caller name derived from rootOptions.name, computed once in constructor. */
455
474
  callerName;
475
+ /**
476
+ * Subject prefixes of the form `{serviceName}__microservice.{kind}.` — one
477
+ * per stream kind this client may publish to. Built once in the constructor
478
+ * so producing a full subject is a single string concat with the user pattern.
479
+ */
480
+ eventSubjectPrefix;
481
+ commandSubjectPrefix;
482
+ orderedSubjectPrefix;
483
+ /**
484
+ * RPC configuration snapshots. The values are derived from rootOptions at
485
+ * construction time so the publish hot path never has to re-run
486
+ * isCoreRpcMode / getRpcTimeout on every call.
487
+ */
488
+ isCoreMode;
489
+ defaultRpcTimeout;
456
490
  /** Shared inbox for JetStream-mode RPC responses. */
457
491
  inbox = null;
458
492
  inboxSubscription = null;
@@ -462,6 +496,12 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
462
496
  pendingTimeouts = /* @__PURE__ */ new Map();
463
497
  /** Subscription to connection status events for disconnect handling. */
464
498
  statusSubscription = null;
499
+ /**
500
+ * Cached readiness flag. Once `connect()` has wired the inbox and status
501
+ * subscription, subsequent publishes skip the `await connect()` microtask
502
+ * and reach for the underlying connection synchronously instead.
503
+ */
504
+ readyForPublish = false;
465
505
  /**
466
506
  * Establish connection. Called automatically by NestJS on first use.
467
507
  *
@@ -472,7 +512,7 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
472
512
  */
473
513
  async connect() {
474
514
  const nc = await this.connection.getConnection();
475
- if (isJetStreamRpcMode(this.rootOptions.rpc) && !this.inboxSubscription) {
515
+ if (!this.isCoreMode && !this.inboxSubscription) {
476
516
  this.setupInbox(nc);
477
517
  }
478
518
  this.statusSubscription ??= this.connection.status$.subscribe((status) => {
@@ -480,12 +520,14 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
480
520
  this.handleDisconnect();
481
521
  }
482
522
  });
523
+ this.readyForPublish = true;
483
524
  return nc;
484
525
  }
485
526
  /** Clean up resources: reject pending RPCs, unsubscribe from status events. */
486
527
  async close() {
487
528
  this.statusSubscription?.unsubscribe();
488
529
  this.statusSubscription = null;
530
+ this.readyForPublish = false;
489
531
  this.rejectPendingRpcs(new Error("Client closed"));
490
532
  }
491
533
  /**
@@ -509,7 +551,7 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
509
551
  * set to the original event subject.
510
552
  */
511
553
  async dispatchEvent(packet) {
512
- await this.connect();
554
+ if (!this.readyForPublish) await this.connect();
513
555
  const { data, hdrs, messageId, schedule, ttl } = this.extractRecordData(packet.data);
514
556
  const eventSubject = this.buildEventSubject(packet.pattern);
515
557
  const msgHeaders = this.buildHeaders(hdrs, { subject: eventSubject });
@@ -548,7 +590,7 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
548
590
  * JetStream mode: publishes to stream + waits for inbox response.
549
591
  */
550
592
  publish(packet, callback) {
551
- const subject = buildSubject(this.targetName, "cmd" /* Command */, packet.pattern);
593
+ const subject = this.commandSubjectPrefix + packet.pattern;
552
594
  const { data, hdrs, timeout, messageId, schedule, ttl } = this.extractRecordData(packet.data);
553
595
  if (schedule) {
554
596
  this.logger.warn(
@@ -565,7 +607,7 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
565
607
  callback({ err: new Error("Internal transport error"), response: null, isDisposed: true });
566
608
  };
567
609
  let jetStreamCorrelationId = null;
568
- if (isCoreRpcMode(this.rootOptions.rpc)) {
610
+ if (this.isCoreMode) {
569
611
  this.publishCoreRpc(subject, data, hdrs, timeout, callback).catch(onUnhandled);
570
612
  } else {
571
613
  jetStreamCorrelationId = import_nuid.nuid.next();
@@ -590,8 +632,8 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
590
632
  /** Core mode: nc.request() with timeout. */
591
633
  async publishCoreRpc(subject, data, customHeaders, timeout, callback) {
592
634
  try {
593
- const nc = await this.connect();
594
- const effectiveTimeout = timeout ?? this.getRpcTimeout();
635
+ const nc = this.readyForPublish ? this.connection.unwrap : await this.connect();
636
+ const effectiveTimeout = timeout ?? this.defaultRpcTimeout;
595
637
  const hdrs = this.buildHeaders(customHeaders, { subject });
596
638
  const response = await nc.request(subject, this.codec.encode(data), {
597
639
  timeout: effectiveTimeout,
@@ -613,10 +655,10 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
613
655
  /** JetStream mode: publish to stream + wait for inbox response. */
614
656
  async publishJetStreamRpc(subject, data, callback, options) {
615
657
  const { headers: customHeaders, correlationId, messageId } = options;
616
- const effectiveTimeout = options.timeout ?? this.getRpcTimeout();
658
+ const effectiveTimeout = options.timeout ?? this.defaultRpcTimeout;
617
659
  this.pendingMessages.set(correlationId, callback);
618
660
  try {
619
- await this.connect();
661
+ if (!this.readyForPublish) await this.connect();
620
662
  if (!this.pendingMessages.has(correlationId)) return;
621
663
  if (!this.inbox) {
622
664
  this.pendingMessages.delete(correlationId);
@@ -662,6 +704,7 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
662
704
  handleDisconnect() {
663
705
  this.rejectPendingRpcs(new Error("Connection lost"));
664
706
  this.inbox = null;
707
+ this.readyForPublish = false;
665
708
  }
666
709
  /** Reject all pending RPC callbacks, clear timeouts, and tear down inbox. */
667
710
  rejectPendingRpcs(error) {
@@ -725,19 +768,22 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
725
768
  this.pendingMessages.delete(correlationId);
726
769
  }
727
770
  }
728
- /** Build event subject — workqueue, broadcast, or ordered. */
771
+ /**
772
+ * Resolve a user pattern to a fully-qualified NATS subject, dispatching
773
+ * between the event, broadcast, and ordered prefixes.
774
+ *
775
+ * The leading-char check short-circuits the `startsWith` comparisons for
776
+ * patterns that cannot possibly carry a broadcast/ordered marker, which is
777
+ * the overwhelmingly common case.
778
+ */
729
779
  buildEventSubject(pattern) {
730
- if (pattern.startsWith("broadcast:" /* Broadcast */)) {
731
- return buildBroadcastSubject(pattern.slice("broadcast:" /* Broadcast */.length));
732
- }
733
- if (pattern.startsWith("ordered:" /* Ordered */)) {
734
- return buildSubject(
735
- this.targetName,
736
- "ordered" /* Ordered */,
737
- pattern.slice("ordered:" /* Ordered */.length)
738
- );
780
+ if (pattern.charCodeAt(0) === 98 && pattern.startsWith("broadcast:" /* Broadcast */)) {
781
+ return BROADCAST_SUBJECT_PREFIX + pattern.slice("broadcast:" /* Broadcast */.length);
739
782
  }
740
- return buildSubject(this.targetName, "ev" /* Event */, pattern);
783
+ if (pattern.charCodeAt(0) === 111 && pattern.startsWith("ordered:" /* Ordered */)) {
784
+ return this.orderedSubjectPrefix + pattern.slice("ordered:" /* Ordered */.length);
785
+ }
786
+ return this.eventSubjectPrefix + pattern;
741
787
  }
742
788
  /** Build NATS headers merging custom headers with transport headers. */
743
789
  buildHeaders(customHeaders, transport) {
@@ -762,7 +808,7 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
762
808
  if (rawData instanceof JetstreamRecord) {
763
809
  return {
764
810
  data: rawData.data,
765
- hdrs: rawData.headers.size > 0 ? new Map(rawData.headers) : null,
811
+ hdrs: rawData.headers.size > 0 ? rawData.headers : null,
766
812
  timeout: rawData.timeout,
767
813
  messageId: rawData.messageId,
768
814
  schedule: rawData.schedule,
@@ -805,11 +851,6 @@ var JetstreamClient = class extends import_microservices.ClientProxy {
805
851
  const pattern = withoutPrefix.slice(dotIndex + 1);
806
852
  return `${targetPrefix}_sch.${pattern}`;
807
853
  }
808
- getRpcTimeout() {
809
- if (!this.rootOptions.rpc) return DEFAULT_RPC_TIMEOUT;
810
- const defaultTimeout = isJetStreamRpcMode(this.rootOptions.rpc) ? DEFAULT_JETSTREAM_RPC_TIMEOUT : DEFAULT_RPC_TIMEOUT;
811
- return this.rootOptions.rpc.timeout ?? defaultTimeout;
812
- }
813
854
  };
814
855
 
815
856
  // src/codec/json.codec.ts
@@ -824,6 +865,19 @@ var JsonCodec = class {
824
865
  }
825
866
  };
826
867
 
868
+ // src/codec/msgpack.codec.ts
869
+ var MsgpackCodec = class {
870
+ constructor(packr) {
871
+ this.packr = packr;
872
+ }
873
+ encode(data) {
874
+ return this.packr.pack(data);
875
+ }
876
+ decode(data) {
877
+ return this.packr.unpack(data);
878
+ }
879
+ };
880
+
827
881
  // src/connection/connection.provider.ts
828
882
  var import_common2 = require("@nestjs/common");
829
883
  var import_transport_node2 = require("@nats-io/transport-node");
@@ -1036,6 +1090,15 @@ var EventBus = class {
1036
1090
  kind
1037
1091
  );
1038
1092
  }
1093
+ /**
1094
+ * Check whether a hook is registered for the given event.
1095
+ *
1096
+ * Used by the routing hot path to elide the emit call entirely when the
1097
+ * transport owner did not register a listener.
1098
+ */
1099
+ hasHook(event) {
1100
+ return this.hooks[event] !== void 0;
1101
+ }
1039
1102
  callHook(event, hook, ...args) {
1040
1103
  try {
1041
1104
  const result = hook(...args);
@@ -1418,16 +1481,71 @@ var resolveAckExtensionInterval = (config, ackWaitNanos) => {
1418
1481
  const interval = Math.floor(ackWaitNanos / 1e6 / 2);
1419
1482
  return Math.max(interval, MIN_ACK_EXTENSION_INTERVAL);
1420
1483
  };
1484
+ var AckExtensionPool = class {
1485
+ entries = /* @__PURE__ */ new Set();
1486
+ handle = null;
1487
+ handleFireAt = 0;
1488
+ schedule(msg, interval) {
1489
+ const entry = {
1490
+ msg,
1491
+ interval,
1492
+ nextFireAt: Date.now() + interval,
1493
+ active: true
1494
+ };
1495
+ this.entries.add(entry);
1496
+ this.ensureWake(entry.nextFireAt);
1497
+ return entry;
1498
+ }
1499
+ cancel(entry) {
1500
+ if (!entry.active) return;
1501
+ entry.active = false;
1502
+ this.entries.delete(entry);
1503
+ if (this.entries.size === 0 && this.handle !== null) {
1504
+ clearTimeout(this.handle);
1505
+ this.handle = null;
1506
+ this.handleFireAt = 0;
1507
+ }
1508
+ }
1509
+ /**
1510
+ * Ensure the shared timer will fire no later than `dueAt`. If an earlier
1511
+ * wake is already scheduled, leave it; otherwise replace it with a tighter one.
1512
+ */
1513
+ ensureWake(dueAt) {
1514
+ if (this.handle !== null && this.handleFireAt <= dueAt) return;
1515
+ if (this.handle !== null) clearTimeout(this.handle);
1516
+ const delay = Math.max(0, dueAt - Date.now());
1517
+ const handle = setTimeout(() => {
1518
+ this.tick();
1519
+ }, delay);
1520
+ if (typeof handle.unref === "function") handle.unref();
1521
+ this.handle = handle;
1522
+ this.handleFireAt = dueAt;
1523
+ }
1524
+ tick() {
1525
+ this.handle = null;
1526
+ this.handleFireAt = 0;
1527
+ const now = Date.now();
1528
+ let earliest = Infinity;
1529
+ for (const entry of this.entries) {
1530
+ if (!entry.active) continue;
1531
+ if (entry.nextFireAt <= now) {
1532
+ try {
1533
+ entry.msg.working();
1534
+ } catch {
1535
+ }
1536
+ entry.nextFireAt = now + entry.interval;
1537
+ }
1538
+ if (entry.nextFireAt < earliest) earliest = entry.nextFireAt;
1539
+ }
1540
+ if (earliest !== Infinity) this.ensureWake(earliest);
1541
+ }
1542
+ };
1543
+ var pool = new AckExtensionPool();
1421
1544
  var startAckExtensionTimer = (msg, interval) => {
1422
1545
  if (interval === null || interval <= 0) return null;
1423
- const timer2 = setInterval(() => {
1424
- try {
1425
- msg.working();
1426
- } catch {
1427
- }
1428
- }, interval);
1546
+ const entry = pool.schedule(msg, interval);
1429
1547
  return () => {
1430
- clearInterval(timer2);
1548
+ pool.cancel(entry);
1431
1549
  };
1432
1550
  };
1433
1551
 
@@ -1441,11 +1559,8 @@ var serializeError = (err) => {
1441
1559
 
1442
1560
  // src/utils/unwrap-result.ts
1443
1561
  var import_rxjs2 = require("rxjs");
1444
- var RESOLVED_VOID = Promise.resolve(void 0);
1445
- var RESOLVED_NULL = Promise.resolve(null);
1446
1562
  var unwrapResult = (result) => {
1447
- if (result === void 0) return RESOLVED_VOID;
1448
- if (result === null) return RESOLVED_NULL;
1563
+ if (result === void 0 || result === null) return result;
1449
1564
  if ((0, import_rxjs2.isObservable)(result)) {
1450
1565
  return subscribeToFirst(result);
1451
1566
  }
@@ -1454,8 +1569,9 @@ var unwrapResult = (result) => {
1454
1569
  (resolved) => (0, import_rxjs2.isObservable)(resolved) ? subscribeToFirst(resolved) : resolved
1455
1570
  );
1456
1571
  }
1457
- return Promise.resolve(result);
1572
+ return result;
1458
1573
  };
1574
+ var isPromiseLike = (value) => value !== null && typeof value === "object" && typeof value.then === "function";
1459
1575
  var subscribeToFirst = (obs) => new Promise((resolve, reject) => {
1460
1576
  let done = false;
1461
1577
  let subscription = null;
@@ -1543,7 +1659,8 @@ var CoreRpcServer = class {
1543
1659
  }
1544
1660
  const ctx = new RpcContext([msg]);
1545
1661
  try {
1546
- const result = await unwrapResult(handler(data, ctx));
1662
+ const raw = unwrapResult(handler(data, ctx));
1663
+ const result = isPromiseLike(raw) ? await raw : raw;
1547
1664
  msg.respond(this.codec.encode(result));
1548
1665
  } catch (err) {
1549
1666
  this.logger.error(`Handler error for Core RPC ${msg.subject}:`, err);
@@ -1566,6 +1683,14 @@ var CoreRpcServer = class {
1566
1683
  var import_common6 = require("@nestjs/common");
1567
1684
  var import_jetstream14 = require("@nats-io/jetstream");
1568
1685
 
1686
+ // src/server/infrastructure/nats-error-codes.ts
1687
+ var NatsErrorCode = /* @__PURE__ */ ((NatsErrorCode2) => {
1688
+ NatsErrorCode2[NatsErrorCode2["ConsumerNotFound"] = 10014] = "ConsumerNotFound";
1689
+ NatsErrorCode2[NatsErrorCode2["ConsumerAlreadyExists"] = 10148] = "ConsumerAlreadyExists";
1690
+ NatsErrorCode2[NatsErrorCode2["StreamNotFound"] = 10059] = "StreamNotFound";
1691
+ return NatsErrorCode2;
1692
+ })(NatsErrorCode || {});
1693
+
1569
1694
  // src/server/infrastructure/stream-config-diff.ts
1570
1695
  var TRANSPORT_CONTROLLED_PROPERTIES = /* @__PURE__ */ new Set([
1571
1696
  "retention"
@@ -2254,13 +2379,17 @@ var MessageProvider = class {
2254
2379
  }
2255
2380
  const defaults = { idle_heartbeat: 5e3 };
2256
2381
  const userOptions = this.consumeOptionsMap.get(kind) ?? {};
2257
- const messages = await consumer.consume({ ...defaults, ...userOptions });
2382
+ const messages = await consumer.consume({
2383
+ ...defaults,
2384
+ ...userOptions,
2385
+ callback: (msg) => {
2386
+ target$.next(msg);
2387
+ }
2388
+ });
2258
2389
  this.activeIterators.add(messages);
2259
2390
  this.monitorConsumerHealth(messages, consumerName2);
2260
2391
  try {
2261
- for await (const msg of messages) {
2262
- target$.next(msg);
2263
- }
2392
+ await messages.closed();
2264
2393
  } finally {
2265
2394
  this.activeIterators.delete(messages);
2266
2395
  }
@@ -2352,11 +2481,16 @@ var MessageProvider = class {
2352
2481
  })
2353
2482
  );
2354
2483
  }
2355
- /** Single iteration: create ordered consumer -> iterate messages. */
2484
+ /** Single iteration: create ordered consumer -> push messages into the subject. */
2356
2485
  async consumeOrderedOnce(streamName2, consumerOpts) {
2357
2486
  const js = this.connection.getJetStreamClient();
2358
2487
  const consumer = await js.consumers.get(streamName2, consumerOpts);
2359
- const messages = await consumer.consume();
2488
+ const orderedMessages$ = this.orderedMessages$;
2489
+ const messages = await consumer.consume({
2490
+ callback: (msg) => {
2491
+ orderedMessages$.next(msg);
2492
+ }
2493
+ });
2360
2494
  if (this.orderedReadyResolve) {
2361
2495
  this.orderedReadyResolve();
2362
2496
  this.orderedReadyResolve = null;
@@ -2364,9 +2498,7 @@ var MessageProvider = class {
2364
2498
  }
2365
2499
  this.activeIterators.add(messages);
2366
2500
  try {
2367
- for await (const msg of messages) {
2368
- this.orderedMessages$.next(msg);
2369
- }
2501
+ await messages.closed();
2370
2502
  } finally {
2371
2503
  this.activeIterators.delete(messages);
2372
2504
  }
@@ -2645,7 +2777,6 @@ var PatternRegistry = class {
2645
2777
 
2646
2778
  // src/server/routing/event.router.ts
2647
2779
  var import_common11 = require("@nestjs/common");
2648
- var import_rxjs4 = require("rxjs");
2649
2780
  var import_transport_node4 = require("@nats-io/transport-node");
2650
2781
  var EventRouter = class {
2651
2782
  constructor(messageProvider, patternRegistry, codec, eventBus, deadLetterConfig, processingConfig, ackWaitMap, connection, options) {
@@ -2684,15 +2815,194 @@ var EventRouter = class {
2684
2815
  }
2685
2816
  this.subscriptions.length = 0;
2686
2817
  }
2687
- /** Subscribe to a message stream and route each message. */
2818
+ /** Subscribe to a message stream and route each message to its handler. */
2688
2819
  subscribeToStream(stream$, kind) {
2689
2820
  const isOrdered = kind === "ordered" /* Ordered */;
2821
+ const patternRegistry = this.patternRegistry;
2822
+ const codec = this.codec;
2823
+ const eventBus = this.eventBus;
2824
+ const logger = this.logger;
2825
+ const deadLetterConfig = this.deadLetterConfig;
2690
2826
  const ackExtensionInterval = isOrdered ? null : resolveAckExtensionInterval(this.getAckExtensionConfig(kind), this.ackWaitMap?.get(kind));
2827
+ const hasAckExtension = ackExtensionInterval !== null && ackExtensionInterval > 0;
2691
2828
  const concurrency = this.getConcurrency(kind);
2692
- const route = (msg) => (0, import_rxjs4.from)(
2693
- isOrdered ? this.handleOrderedSafe(msg) : this.handleSafe(msg, ackExtensionInterval, kind)
2694
- );
2695
- const subscription = stream$.pipe(isOrdered ? (0, import_rxjs4.concatMap)(route) : (0, import_rxjs4.mergeMap)(route, concurrency)).subscribe();
2829
+ const hasDlqCheck = deadLetterConfig !== void 0;
2830
+ const emitRouted = eventBus.hasHook("messageRouted" /* MessageRouted */);
2831
+ const isDeadLetter = (msg) => {
2832
+ if (!hasDlqCheck) return false;
2833
+ const maxDeliver = deadLetterConfig.maxDeliverByStream?.get(msg.info.stream);
2834
+ if (maxDeliver === void 0 || maxDeliver <= 0) return false;
2835
+ return msg.info.deliveryCount >= maxDeliver;
2836
+ };
2837
+ const handleDeadLetter = hasDlqCheck ? (msg, data, err) => this.handleDeadLetter(msg, data, err) : null;
2838
+ const settleSuccess = (msg, ctx) => {
2839
+ if (ctx.shouldTerminate) msg.term(ctx.terminateReason);
2840
+ else if (ctx.shouldRetry) msg.nak(ctx.retryDelay);
2841
+ else msg.ack();
2842
+ };
2843
+ const settleFailure = async (msg, data, err) => {
2844
+ if (handleDeadLetter !== null && isDeadLetter(msg)) {
2845
+ await handleDeadLetter(msg, data, err);
2846
+ return;
2847
+ }
2848
+ msg.nak();
2849
+ };
2850
+ const resolveEvent = (msg) => {
2851
+ const subject = msg.subject;
2852
+ try {
2853
+ const handler = patternRegistry.getHandler(subject);
2854
+ if (!handler) {
2855
+ msg.term(`No handler for event: ${subject}`);
2856
+ logger.error(`No handler for subject: ${subject}`);
2857
+ return null;
2858
+ }
2859
+ let data;
2860
+ try {
2861
+ data = codec.decode(msg.data);
2862
+ } catch (err) {
2863
+ msg.term("Decode error");
2864
+ logger.error(`Decode error for ${subject}:`, err);
2865
+ return null;
2866
+ }
2867
+ if (emitRouted) eventBus.emitMessageRouted(subject, "event" /* Event */);
2868
+ return { handler, data };
2869
+ } catch (err) {
2870
+ logger.error(`Unexpected error in ${kind} event router`, err);
2871
+ try {
2872
+ msg.term("Unexpected router error");
2873
+ } catch (termErr) {
2874
+ logger.error(`Failed to terminate message ${subject}:`, termErr);
2875
+ }
2876
+ return null;
2877
+ }
2878
+ };
2879
+ const handleSafe = (msg) => {
2880
+ const resolved = resolveEvent(msg);
2881
+ if (resolved === null) return void 0;
2882
+ const { handler, data } = resolved;
2883
+ const ctx = new RpcContext([msg]);
2884
+ const stopAckExtension = hasAckExtension ? startAckExtensionTimer(msg, ackExtensionInterval) : null;
2885
+ let pending;
2886
+ try {
2887
+ pending = unwrapResult(handler(data, ctx));
2888
+ } catch (err) {
2889
+ logger.error(`Event handler error (${msg.subject}) in ${kind} router:`, err);
2890
+ if (stopAckExtension !== null) stopAckExtension();
2891
+ return settleFailure(msg, data, err);
2892
+ }
2893
+ if (!isPromiseLike(pending)) {
2894
+ settleSuccess(msg, ctx);
2895
+ if (stopAckExtension !== null) stopAckExtension();
2896
+ return void 0;
2897
+ }
2898
+ return pending.then(
2899
+ () => {
2900
+ settleSuccess(msg, ctx);
2901
+ if (stopAckExtension !== null) stopAckExtension();
2902
+ },
2903
+ async (err) => {
2904
+ logger.error(`Event handler error (${msg.subject}) in ${kind} router:`, err);
2905
+ try {
2906
+ await settleFailure(msg, data, err);
2907
+ } finally {
2908
+ if (stopAckExtension !== null) stopAckExtension();
2909
+ }
2910
+ }
2911
+ );
2912
+ };
2913
+ const handleOrderedSafe = (msg) => {
2914
+ const subject = msg.subject;
2915
+ let handler;
2916
+ let data;
2917
+ try {
2918
+ handler = patternRegistry.getHandler(subject);
2919
+ if (!handler) {
2920
+ logger.error(`No handler for subject: ${subject}`);
2921
+ return void 0;
2922
+ }
2923
+ try {
2924
+ data = codec.decode(msg.data);
2925
+ } catch (err) {
2926
+ logger.error(`Decode error for ${subject}:`, err);
2927
+ return void 0;
2928
+ }
2929
+ if (emitRouted) eventBus.emitMessageRouted(subject, "event" /* Event */);
2930
+ } catch (err) {
2931
+ logger.error(`Ordered handler error (${subject}):`, err);
2932
+ return void 0;
2933
+ }
2934
+ const ctx = new RpcContext([msg]);
2935
+ const warnIfSettlementAttempted = () => {
2936
+ if (ctx.shouldRetry || ctx.shouldTerminate) {
2937
+ logger.warn(
2938
+ `retry()/terminate() ignored for ordered message ${subject} \u2014 ordered consumers auto-acknowledge`
2939
+ );
2940
+ }
2941
+ };
2942
+ let pending;
2943
+ try {
2944
+ pending = unwrapResult(handler(data, ctx));
2945
+ } catch (err) {
2946
+ logger.error(`Ordered handler error (${subject}):`, err);
2947
+ return void 0;
2948
+ }
2949
+ if (!isPromiseLike(pending)) {
2950
+ warnIfSettlementAttempted();
2951
+ return void 0;
2952
+ }
2953
+ return pending.then(warnIfSettlementAttempted, (err) => {
2954
+ logger.error(`Ordered handler error (${subject}):`, err);
2955
+ });
2956
+ };
2957
+ const route = isOrdered ? handleOrderedSafe : handleSafe;
2958
+ const maxActive = isOrdered ? 1 : concurrency ?? Number.POSITIVE_INFINITY;
2959
+ const backlogWarnThreshold = 1e3;
2960
+ let active = 0;
2961
+ let backlogWarned = false;
2962
+ const backlog = [];
2963
+ const onAsyncDone = () => {
2964
+ active--;
2965
+ drainBacklog();
2966
+ };
2967
+ const drainBacklog = () => {
2968
+ while (active < maxActive) {
2969
+ const next = backlog.shift();
2970
+ if (next === void 0) return;
2971
+ active++;
2972
+ const result = route(next);
2973
+ if (result !== void 0) {
2974
+ void result.finally(onAsyncDone);
2975
+ } else {
2976
+ active--;
2977
+ }
2978
+ }
2979
+ if (backlog.length < backlogWarnThreshold) backlogWarned = false;
2980
+ };
2981
+ const subscription = stream$.subscribe({
2982
+ next: (msg) => {
2983
+ if (active >= maxActive) {
2984
+ backlog.push(msg);
2985
+ if (!backlogWarned && backlog.length >= backlogWarnThreshold) {
2986
+ backlogWarned = true;
2987
+ logger.warn(
2988
+ `${kind} backlog reached ${backlog.length} messages \u2014 consumer may be falling behind`
2989
+ );
2990
+ }
2991
+ return;
2992
+ }
2993
+ active++;
2994
+ const result = route(msg);
2995
+ if (result !== void 0) {
2996
+ void result.finally(onAsyncDone);
2997
+ } else {
2998
+ active--;
2999
+ if (backlog.length > 0) drainBacklog();
3000
+ }
3001
+ },
3002
+ error: (err) => {
3003
+ logger.error(`Stream error in ${kind} router`, err);
3004
+ }
3005
+ });
2696
3006
  this.subscriptions.push(subscription);
2697
3007
  }
2698
3008
  getConcurrency(kind) {
@@ -2705,86 +3015,6 @@ var EventRouter = class {
2705
3015
  if (kind === "broadcast" /* Broadcast */) return this.processingConfig?.broadcast?.ackExtension;
2706
3016
  return void 0;
2707
3017
  }
2708
- /** Handle a single event message with error isolation. */
2709
- async handleSafe(msg, ackExtensionInterval, kind) {
2710
- try {
2711
- const resolved = this.decodeMessage(msg);
2712
- if (!resolved) return;
2713
- await this.executeHandler(
2714
- resolved.handler,
2715
- resolved.data,
2716
- resolved.ctx,
2717
- msg,
2718
- ackExtensionInterval
2719
- );
2720
- } catch (err) {
2721
- this.logger.error(`Unexpected error in ${kind} event router`, err);
2722
- }
2723
- }
2724
- /** Handle an ordered message with error isolation. */
2725
- async handleOrderedSafe(msg) {
2726
- try {
2727
- const resolved = this.decodeMessage(msg, true);
2728
- if (!resolved) return;
2729
- await unwrapResult(resolved.handler(resolved.data, resolved.ctx));
2730
- if (resolved.ctx.shouldRetry || resolved.ctx.shouldTerminate) {
2731
- this.logger.warn(
2732
- `retry()/terminate() ignored for ordered message ${msg.subject} \u2014 ordered consumers auto-acknowledge`
2733
- );
2734
- }
2735
- } catch (err) {
2736
- this.logger.error(`Ordered handler error (${msg.subject}):`, err);
2737
- }
2738
- }
2739
- /** Resolve handler, decode payload, and build context. Returns null on failure. */
2740
- decodeMessage(msg, isOrdered = false) {
2741
- const handler = this.patternRegistry.getHandler(msg.subject);
2742
- if (!handler) {
2743
- if (!isOrdered) msg.term(`No handler for event: ${msg.subject}`);
2744
- this.logger.error(`No handler for subject: ${msg.subject}`);
2745
- return null;
2746
- }
2747
- let data;
2748
- try {
2749
- data = this.codec.decode(msg.data);
2750
- } catch (err) {
2751
- if (!isOrdered) msg.term("Decode error");
2752
- this.logger.error(`Decode error for ${msg.subject}:`, err);
2753
- return null;
2754
- }
2755
- this.eventBus.emitMessageRouted(msg.subject, "event" /* Event */);
2756
- return { handler, data, ctx: new RpcContext([msg]) };
2757
- }
2758
- /** Execute handler, then ack on success or nak/dead-letter on failure. */
2759
- async executeHandler(handler, data, ctx, msg, ackExtensionInterval) {
2760
- const stopAckExtension = startAckExtensionTimer(msg, ackExtensionInterval);
2761
- try {
2762
- await unwrapResult(handler(data, ctx));
2763
- if (ctx.shouldTerminate) {
2764
- msg.term(ctx.terminateReason);
2765
- } else if (ctx.shouldRetry) {
2766
- msg.nak(ctx.retryDelay);
2767
- } else {
2768
- msg.ack();
2769
- }
2770
- } catch (err) {
2771
- this.logger.error(`Event handler error (${msg.subject}):`, err);
2772
- if (this.isDeadLetter(msg)) {
2773
- await this.handleDeadLetter(msg, data, err);
2774
- } else {
2775
- msg.nak();
2776
- }
2777
- } finally {
2778
- stopAckExtension?.();
2779
- }
2780
- }
2781
- /** Check if the message has exhausted all delivery attempts. */
2782
- isDeadLetter(msg) {
2783
- if (!this.deadLetterConfig) return false;
2784
- const maxDeliver = this.deadLetterConfig.maxDeliverByStream.get(msg.info.stream);
2785
- if (maxDeliver === void 0 || maxDeliver <= 0) return false;
2786
- return msg.info.deliveryCount >= maxDeliver;
2787
- }
2788
3018
  /** Handle a dead letter: invoke callback, then term or nak based on result. */
2789
3019
  /**
2790
3020
  * Fallback execution for a dead letter when DLQ is disabled, or when
@@ -2896,7 +3126,6 @@ var EventRouter = class {
2896
3126
  // src/server/routing/rpc.router.ts
2897
3127
  var import_common12 = require("@nestjs/common");
2898
3128
  var import_transport_node5 = require("@nats-io/transport-node");
2899
- var import_rxjs5 = require("rxjs");
2900
3129
  var RpcRouter = class {
2901
3130
  constructor(messageProvider, patternRegistry, connection, codec, eventBus, rpcOptions, ackWaitMap) {
2902
3131
  this.messageProvider = messageProvider;
@@ -2927,87 +3156,178 @@ var RpcRouter = class {
2927
3156
  /** Start routing command messages to handlers. */
2928
3157
  async start() {
2929
3158
  this.cachedNc = await this.connection.getConnection();
2930
- this.subscription = this.messageProvider.commands$.pipe((0, import_rxjs5.mergeMap)((msg) => (0, import_rxjs5.from)(this.handleSafe(msg)), this.concurrency)).subscribe();
2931
- }
2932
- /** Stop routing and unsubscribe. */
2933
- destroy() {
2934
- this.subscription?.unsubscribe();
2935
- this.subscription = null;
2936
- }
2937
- /** Handle a single RPC command message with error isolation. */
2938
- async handleSafe(msg) {
2939
- try {
2940
- const handler = this.patternRegistry.getHandler(msg.subject);
2941
- if (!handler) {
2942
- msg.term(`No handler for RPC: ${msg.subject}`);
2943
- this.logger.error(`No handler for RPC subject: ${msg.subject}`);
2944
- return;
2945
- }
2946
- const { headers: msgHeaders } = msg;
2947
- const replyTo = msgHeaders?.get("x-reply-to" /* ReplyTo */);
2948
- const correlationId = msgHeaders?.get("x-correlation-id" /* CorrelationId */);
2949
- if (!replyTo || !correlationId) {
2950
- msg.term("Missing required headers (reply-to or correlation-id)");
2951
- this.logger.error(`Missing headers for RPC: ${msg.subject}`);
2952
- return;
2953
- }
2954
- let data;
2955
- try {
2956
- data = this.codec.decode(msg.data);
2957
- } catch (err) {
2958
- msg.term("Decode error");
2959
- this.logger.error(`Decode error for RPC ${msg.subject}:`, err);
2960
- return;
2961
- }
2962
- this.eventBus.emitMessageRouted(msg.subject, "rpc" /* Rpc */);
2963
- await this.executeHandler(handler, data, msg, replyTo, correlationId);
2964
- } catch (err) {
2965
- this.logger.error("Unexpected error in RPC router", err);
2966
- }
2967
- }
2968
- /** Execute handler, publish response, settle message. */
2969
- async executeHandler(handler, data, msg, replyTo, correlationId) {
2970
- const nc = this.cachedNc ?? await this.connection.getConnection();
2971
- const ctx = new RpcContext([msg]);
2972
- let settled = false;
2973
- const stopAckExtension = startAckExtensionTimer(msg, this.ackExtensionInterval);
2974
- const timeoutId = setTimeout(() => {
2975
- if (settled) return;
2976
- settled = true;
2977
- stopAckExtension?.();
2978
- this.logger.error(`RPC timeout (${this.timeout}ms): ${msg.subject}`);
2979
- this.eventBus.emit("rpcTimeout" /* RpcTimeout */, msg.subject, correlationId);
2980
- msg.term("Handler timeout");
2981
- }, this.timeout);
2982
- try {
2983
- const result = await unwrapResult(handler(data, ctx));
2984
- if (settled) return;
2985
- settled = true;
2986
- clearTimeout(timeoutId);
2987
- stopAckExtension?.();
2988
- msg.ack();
3159
+ const nc = this.cachedNc;
3160
+ const patternRegistry = this.patternRegistry;
3161
+ const codec = this.codec;
3162
+ const eventBus = this.eventBus;
3163
+ const logger = this.logger;
3164
+ const timeout = this.timeout;
3165
+ const ackExtensionInterval = this.ackExtensionInterval;
3166
+ const hasAckExtension = ackExtensionInterval !== null && ackExtensionInterval > 0;
3167
+ const maxActive = this.concurrency ?? Number.POSITIVE_INFINITY;
3168
+ const emitRpcTimeout = (subject, correlationId) => {
3169
+ eventBus.emit("rpcTimeout" /* RpcTimeout */, subject, correlationId);
3170
+ };
3171
+ const publishReply = (replyTo, correlationId, payload) => {
2989
3172
  try {
2990
3173
  const hdrs = (0, import_transport_node5.headers)();
2991
3174
  hdrs.set("x-correlation-id" /* CorrelationId */, correlationId);
2992
- nc.publish(replyTo, this.codec.encode(result), { headers: hdrs });
3175
+ nc.publish(replyTo, codec.encode(payload), { headers: hdrs });
2993
3176
  } catch (publishErr) {
2994
- this.logger.error(`Failed to publish RPC response for ${msg.subject}`, publishErr);
3177
+ logger.error(`Failed to publish RPC response`, publishErr);
2995
3178
  }
2996
- } catch (err) {
2997
- if (settled) return;
2998
- settled = true;
2999
- clearTimeout(timeoutId);
3000
- stopAckExtension?.();
3179
+ };
3180
+ const publishErrorReply = (replyTo, correlationId, subject, err) => {
3001
3181
  try {
3002
3182
  const hdrs = (0, import_transport_node5.headers)();
3003
3183
  hdrs.set("x-correlation-id" /* CorrelationId */, correlationId);
3004
3184
  hdrs.set("x-error" /* Error */, "true");
3005
- nc.publish(replyTo, this.codec.encode(serializeError(err)), { headers: hdrs });
3185
+ nc.publish(replyTo, codec.encode(serializeError(err)), { headers: hdrs });
3006
3186
  } catch (encodeErr) {
3007
- this.logger.error(`Failed to encode RPC error for ${msg.subject}`, encodeErr);
3187
+ logger.error(`Failed to encode RPC error for ${subject}`, encodeErr);
3008
3188
  }
3009
- msg.term(`Handler error: ${msg.subject}`);
3010
- }
3189
+ };
3190
+ const resolveCommand = (msg) => {
3191
+ const subject = msg.subject;
3192
+ try {
3193
+ const handler = patternRegistry.getHandler(subject);
3194
+ if (!handler) {
3195
+ msg.term(`No handler for RPC: ${subject}`);
3196
+ logger.error(`No handler for RPC subject: ${subject}`);
3197
+ return null;
3198
+ }
3199
+ const msgHeaders = msg.headers;
3200
+ const replyTo = msgHeaders?.get("x-reply-to" /* ReplyTo */);
3201
+ const correlationId = msgHeaders?.get("x-correlation-id" /* CorrelationId */);
3202
+ if (!replyTo || !correlationId) {
3203
+ msg.term("Missing required headers (reply-to or correlation-id)");
3204
+ logger.error(`Missing headers for RPC: ${subject}`);
3205
+ return null;
3206
+ }
3207
+ let data;
3208
+ try {
3209
+ data = codec.decode(msg.data);
3210
+ } catch (err) {
3211
+ msg.term("Decode error");
3212
+ logger.error(`Decode error for RPC ${subject}:`, err);
3213
+ return null;
3214
+ }
3215
+ eventBus.emitMessageRouted(subject, "rpc" /* Rpc */);
3216
+ return { handler, data, replyTo, correlationId };
3217
+ } catch (err) {
3218
+ logger.error("Unexpected error in RPC router", err);
3219
+ try {
3220
+ msg.term("Unexpected router error");
3221
+ } catch (termErr) {
3222
+ logger.error(`Failed to terminate RPC message ${subject}:`, termErr);
3223
+ }
3224
+ return null;
3225
+ }
3226
+ };
3227
+ const handleSafe = (msg) => {
3228
+ const resolved = resolveCommand(msg);
3229
+ if (resolved === null) return void 0;
3230
+ const { handler, data, replyTo, correlationId } = resolved;
3231
+ const subject = msg.subject;
3232
+ const ctx = new RpcContext([msg]);
3233
+ const stopAckExtension = hasAckExtension ? startAckExtensionTimer(msg, ackExtensionInterval) : null;
3234
+ let pending;
3235
+ try {
3236
+ pending = unwrapResult(handler(data, ctx));
3237
+ } catch (err) {
3238
+ if (stopAckExtension !== null) stopAckExtension();
3239
+ logger.error(`RPC handler error (${subject}):`, err);
3240
+ publishErrorReply(replyTo, correlationId, subject, err);
3241
+ msg.term(`Handler error: ${subject}`);
3242
+ return void 0;
3243
+ }
3244
+ if (!isPromiseLike(pending)) {
3245
+ if (stopAckExtension !== null) stopAckExtension();
3246
+ msg.ack();
3247
+ publishReply(replyTo, correlationId, pending);
3248
+ return void 0;
3249
+ }
3250
+ let settled = false;
3251
+ const timeoutId = setTimeout(() => {
3252
+ if (settled) return;
3253
+ settled = true;
3254
+ if (stopAckExtension !== null) stopAckExtension();
3255
+ logger.error(`RPC timeout (${timeout}ms): ${subject}`);
3256
+ emitRpcTimeout(subject, correlationId);
3257
+ msg.term("Handler timeout");
3258
+ }, timeout);
3259
+ return pending.then(
3260
+ (result) => {
3261
+ if (settled) return;
3262
+ settled = true;
3263
+ clearTimeout(timeoutId);
3264
+ if (stopAckExtension !== null) stopAckExtension();
3265
+ msg.ack();
3266
+ publishReply(replyTo, correlationId, result);
3267
+ },
3268
+ (err) => {
3269
+ if (settled) return;
3270
+ settled = true;
3271
+ clearTimeout(timeoutId);
3272
+ if (stopAckExtension !== null) stopAckExtension();
3273
+ logger.error(`RPC handler error (${subject}):`, err);
3274
+ publishErrorReply(replyTo, correlationId, subject, err);
3275
+ msg.term(`Handler error: ${subject}`);
3276
+ }
3277
+ );
3278
+ };
3279
+ const backlogWarnThreshold = 1e3;
3280
+ let active = 0;
3281
+ let backlogWarned = false;
3282
+ const backlog = [];
3283
+ const onAsyncDone = () => {
3284
+ active--;
3285
+ drainBacklog();
3286
+ };
3287
+ const drainBacklog = () => {
3288
+ while (active < maxActive) {
3289
+ const next = backlog.shift();
3290
+ if (next === void 0) return;
3291
+ active++;
3292
+ const result = handleSafe(next);
3293
+ if (result !== void 0) {
3294
+ void result.finally(onAsyncDone);
3295
+ } else {
3296
+ active--;
3297
+ }
3298
+ }
3299
+ if (backlog.length < backlogWarnThreshold) backlogWarned = false;
3300
+ };
3301
+ this.subscription = this.messageProvider.commands$.subscribe({
3302
+ next: (msg) => {
3303
+ if (active >= maxActive) {
3304
+ backlog.push(msg);
3305
+ if (!backlogWarned && backlog.length >= backlogWarnThreshold) {
3306
+ backlogWarned = true;
3307
+ logger.warn(
3308
+ `RPC backlog reached ${backlog.length} messages \u2014 consumer may be falling behind`
3309
+ );
3310
+ }
3311
+ return;
3312
+ }
3313
+ active++;
3314
+ const result = handleSafe(msg);
3315
+ if (result !== void 0) {
3316
+ void result.finally(onAsyncDone);
3317
+ } else {
3318
+ active--;
3319
+ if (backlog.length > 0) drainBacklog();
3320
+ }
3321
+ },
3322
+ error: (err) => {
3323
+ logger.error("Stream error in RPC router", err);
3324
+ }
3325
+ });
3326
+ }
3327
+ /** Stop routing and unsubscribe. */
3328
+ destroy() {
3329
+ this.subscription?.unsubscribe();
3330
+ this.subscription = null;
3011
3331
  }
3012
3332
  };
3013
3333
 
@@ -3456,14 +3776,23 @@ JetstreamModule = __decorateClass([
3456
3776
  ], JetstreamModule);
3457
3777
  // Annotate the CommonJS export names for ESM import in node:
3458
3778
  0 && (module.exports = {
3779
+ DEFAULT_BROADCAST_CONSUMER_CONFIG,
3780
+ DEFAULT_BROADCAST_STREAM_CONFIG,
3781
+ DEFAULT_COMMAND_CONSUMER_CONFIG,
3782
+ DEFAULT_COMMAND_STREAM_CONFIG,
3783
+ DEFAULT_DLQ_STREAM_CONFIG,
3784
+ DEFAULT_EVENT_CONSUMER_CONFIG,
3785
+ DEFAULT_EVENT_STREAM_CONFIG,
3786
+ DEFAULT_JETSTREAM_RPC_TIMEOUT,
3459
3787
  DEFAULT_METADATA_BUCKET,
3460
3788
  DEFAULT_METADATA_HISTORY,
3461
3789
  DEFAULT_METADATA_REPLICAS,
3462
3790
  DEFAULT_METADATA_TTL,
3463
- EventBus,
3791
+ DEFAULT_ORDERED_STREAM_CONFIG,
3792
+ DEFAULT_RPC_TIMEOUT,
3793
+ DEFAULT_SHUTDOWN_TIMEOUT,
3464
3794
  JETSTREAM_CODEC,
3465
3795
  JETSTREAM_CONNECTION,
3466
- JETSTREAM_EVENT_BUS,
3467
3796
  JETSTREAM_OPTIONS,
3468
3797
  JetstreamClient,
3469
3798
  JetstreamDlqHeader,
@@ -3476,7 +3805,10 @@ JetstreamModule = __decorateClass([
3476
3805
  JsonCodec,
3477
3806
  MIN_METADATA_TTL,
3478
3807
  MessageKind,
3808
+ MsgpackCodec,
3809
+ NatsErrorCode,
3479
3810
  PatternPrefix,
3811
+ RESERVED_HEADERS,
3480
3812
  RpcContext,
3481
3813
  StreamKind,
3482
3814
  TransportEvent,