@horizon-republic/nestjs-jetstream 2.8.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/README.md +15 -2
- package/dist/index.cjs +1313 -281
- package/dist/index.d.cts +467 -37
- package/dist/index.d.ts +467 -37
- package/dist/index.js +1275 -264
- package/package.json +31 -16
package/dist/index.d.cts
CHANGED
|
@@ -117,6 +117,14 @@ interface JetstreamHealthStatus {
|
|
|
117
117
|
latency: number | null;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Stream config overrides exposed to users.
|
|
122
|
+
*
|
|
123
|
+
* `retention` is excluded because it is controlled by the transport layer
|
|
124
|
+
* (Workqueue for events/commands, Limits for broadcast/ordered).
|
|
125
|
+
* Any `retention` value provided at runtime is silently stripped.
|
|
126
|
+
*/
|
|
127
|
+
type StreamConfigOverrides = Partial<Omit<StreamConfig, 'retention'>>;
|
|
120
128
|
/**
|
|
121
129
|
* RPC transport configuration.
|
|
122
130
|
*
|
|
@@ -136,7 +144,7 @@ type RpcConfig = {
|
|
|
136
144
|
/** Handler timeout in ms. Default: 180_000 (3 min). */
|
|
137
145
|
timeout?: number;
|
|
138
146
|
/** Raw NATS StreamConfig overrides for the command stream. */
|
|
139
|
-
stream?:
|
|
147
|
+
stream?: StreamConfigOverrides;
|
|
140
148
|
/** Raw NATS ConsumerConfig overrides for the command consumer. */
|
|
141
149
|
consumer?: Partial<ConsumerConfig>;
|
|
142
150
|
/** Options passed to the nats.js `consumer.consume()` call for the command consumer. */
|
|
@@ -151,7 +159,7 @@ type RpcConfig = {
|
|
|
151
159
|
};
|
|
152
160
|
/** Overrides for JetStream stream and consumer configuration. */
|
|
153
161
|
interface StreamConsumerOverrides {
|
|
154
|
-
stream?:
|
|
162
|
+
stream?: StreamConfigOverrides;
|
|
155
163
|
consumer?: Partial<ConsumerConfig>;
|
|
156
164
|
/**
|
|
157
165
|
* Options passed to the nats.js `consumer.consume()` call.
|
|
@@ -195,7 +203,7 @@ interface StreamConsumerOverrides {
|
|
|
195
203
|
*/
|
|
196
204
|
interface OrderedEventOverrides {
|
|
197
205
|
/** Stream overrides (e.g. `max_age`, `max_bytes`). */
|
|
198
|
-
stream?:
|
|
206
|
+
stream?: StreamConfigOverrides;
|
|
199
207
|
/**
|
|
200
208
|
* Where to start reading when the consumer is (re)created.
|
|
201
209
|
* @default DeliverPolicy.All
|
|
@@ -215,6 +223,38 @@ interface OrderedEventOverrides {
|
|
|
215
223
|
*/
|
|
216
224
|
replayPolicy?: ReplayPolicy;
|
|
217
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Configuration for the handler metadata KV registry.
|
|
228
|
+
*
|
|
229
|
+
* When any handler has `meta` in its extras, the transport writes metadata
|
|
230
|
+
* entries to a NATS KV bucket at startup. External services (API gateways,
|
|
231
|
+
* dashboards) can watch the bucket for service discovery.
|
|
232
|
+
*
|
|
233
|
+
* All fields are optional — sensible defaults are applied.
|
|
234
|
+
*/
|
|
235
|
+
interface MetadataRegistryOptions {
|
|
236
|
+
/**
|
|
237
|
+
* KV bucket name.
|
|
238
|
+
* @default 'handler_registry'
|
|
239
|
+
*/
|
|
240
|
+
bucket?: string;
|
|
241
|
+
/**
|
|
242
|
+
* Number of KV bucket replicas. Must be an odd number (1, 3, 5, 7, ...).
|
|
243
|
+
* Requires a NATS cluster with at least this many nodes.
|
|
244
|
+
* @default 1
|
|
245
|
+
*/
|
|
246
|
+
replicas?: number;
|
|
247
|
+
/**
|
|
248
|
+
* KV bucket TTL in milliseconds.
|
|
249
|
+
*
|
|
250
|
+
* Entries expire automatically unless refreshed by a heartbeat.
|
|
251
|
+
* The transport refreshes entries every `ttl / 2` while the pod is alive.
|
|
252
|
+
* When the pod stops (graceful or crash), entries expire after this duration.
|
|
253
|
+
*
|
|
254
|
+
* @default 30_000 (30 seconds)
|
|
255
|
+
*/
|
|
256
|
+
ttl?: number;
|
|
257
|
+
}
|
|
218
258
|
/**
|
|
219
259
|
* Root module configuration for `JetstreamModule.forRoot()`.
|
|
220
260
|
*
|
|
@@ -283,12 +323,62 @@ interface JetstreamModuleOptions {
|
|
|
283
323
|
* ```
|
|
284
324
|
*/
|
|
285
325
|
onDeadLetter?(info: DeadLetterInfo): Promise<void>;
|
|
326
|
+
/**
|
|
327
|
+
* Dead-letter queue (DLQ) configuration.
|
|
328
|
+
* DLQ is a separate stream used to store messages that have exhausted all delivery attempts.
|
|
329
|
+
* @example
|
|
330
|
+
* ```typescript
|
|
331
|
+
* JetstreamModule.forRootAsync({
|
|
332
|
+
* name: 'my-service',
|
|
333
|
+
* servers: ['nats://localhost:4222'],
|
|
334
|
+
* dlq: {
|
|
335
|
+
* stream: {
|
|
336
|
+
* max_age: toNanos(30, 'days'),
|
|
337
|
+
* },
|
|
338
|
+
* },
|
|
339
|
+
* })
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
342
|
+
dlq?: {
|
|
343
|
+
stream?: StreamConfigOverrides;
|
|
344
|
+
};
|
|
286
345
|
/**
|
|
287
346
|
* Graceful shutdown timeout in ms.
|
|
288
347
|
* Handlers exceeding this are abandoned.
|
|
289
348
|
* @default 10_000
|
|
290
349
|
*/
|
|
291
350
|
shutdownTimeout?: number;
|
|
351
|
+
/**
|
|
352
|
+
* Allow destructive stream migration when immutable config changes are detected.
|
|
353
|
+
*
|
|
354
|
+
* When `true`, the transport will recreate streams (via blue-green sourcing)
|
|
355
|
+
* if immutable properties like `storage` differ from the running stream.
|
|
356
|
+
* Messages are preserved during migration.
|
|
357
|
+
*
|
|
358
|
+
* `retention` is NOT migratable — it is controlled by the transport
|
|
359
|
+
* (Workqueue for events, Limits for broadcast/ordered) and a mismatch
|
|
360
|
+
* is always treated as an error regardless of this flag.
|
|
361
|
+
*
|
|
362
|
+
* When `false` (default), immutable conflicts are logged as warnings and
|
|
363
|
+
* the stream continues with its existing configuration.
|
|
364
|
+
*
|
|
365
|
+
* @default false
|
|
366
|
+
*/
|
|
367
|
+
allowDestructiveMigration?: boolean;
|
|
368
|
+
/**
|
|
369
|
+
* Handler metadata KV registry configuration.
|
|
370
|
+
*
|
|
371
|
+
* When any handler has `meta` in its `@EventPattern` / `@MessagePattern` extras,
|
|
372
|
+
* the transport writes metadata to a NATS KV bucket at startup.
|
|
373
|
+
* External services (API gateways, dashboards, CLI tools) can read or watch
|
|
374
|
+
* the bucket for dynamic service discovery.
|
|
375
|
+
*
|
|
376
|
+
* Auto-enabled when any handler has `meta`. Set to customize bucket name,
|
|
377
|
+
* replicas, or TTL.
|
|
378
|
+
*
|
|
379
|
+
* @see MetadataRegistryOptions
|
|
380
|
+
*/
|
|
381
|
+
metadata?: MetadataRegistryOptions;
|
|
292
382
|
/**
|
|
293
383
|
* Raw NATS ConnectionOptions pass-through for advanced connection config.
|
|
294
384
|
* Allows setting tls, auth, reconnect behavior, maxReconnectAttempts, etc.
|
|
@@ -435,6 +525,13 @@ declare class EventBus {
|
|
|
435
525
|
* Avoids rest/spread overhead of the generic `emit()`.
|
|
436
526
|
*/
|
|
437
527
|
emitMessageRouted(subject: string, kind: MessageKind): void;
|
|
528
|
+
/**
|
|
529
|
+
* Check whether a hook is registered for the given event.
|
|
530
|
+
*
|
|
531
|
+
* Used by the routing hot path to elide the emit call entirely when the
|
|
532
|
+
* transport owner did not register a listener.
|
|
533
|
+
*/
|
|
534
|
+
hasHook(event: keyof TransportHooks): boolean;
|
|
438
535
|
private callHook;
|
|
439
536
|
}
|
|
440
537
|
|
|
@@ -516,6 +613,7 @@ declare class PatternRegistry {
|
|
|
516
613
|
private _hasCommands;
|
|
517
614
|
private _hasBroadcasts;
|
|
518
615
|
private _hasOrdered;
|
|
616
|
+
private _hasMetadata;
|
|
519
617
|
constructor(options: JetstreamModuleOptions);
|
|
520
618
|
/**
|
|
521
619
|
* Register all handlers from the NestJS strategy.
|
|
@@ -533,11 +631,21 @@ declare class PatternRegistry {
|
|
|
533
631
|
hasOrderedHandlers(): boolean;
|
|
534
632
|
/** Get fully-qualified NATS subjects for ordered handlers. */
|
|
535
633
|
getOrderedSubjects(): string[];
|
|
634
|
+
/** Check if any registered handler has metadata. */
|
|
635
|
+
hasMetadata(): boolean;
|
|
636
|
+
/**
|
|
637
|
+
* Get handler metadata entries for KV publishing.
|
|
638
|
+
*
|
|
639
|
+
* Returns a map of KV key -> metadata object for all handlers that have `meta`.
|
|
640
|
+
* Key format: `{serviceName}.{kind}.{pattern}`.
|
|
641
|
+
*/
|
|
642
|
+
getMetadataEntries(): Map<string, Record<string, unknown>>;
|
|
536
643
|
/** Get patterns grouped by kind (cached after registration). */
|
|
537
644
|
getPatternsByKind(): PatternsByKind;
|
|
538
645
|
/** Normalize a full NATS subject back to the user-facing pattern. */
|
|
539
646
|
normalizeSubject(subject: string): string;
|
|
540
647
|
private buildPatternsByKind;
|
|
648
|
+
private resolveStreamKind;
|
|
541
649
|
private logSummary;
|
|
542
650
|
}
|
|
543
651
|
|
|
@@ -582,12 +690,14 @@ declare class StreamProvider {
|
|
|
582
690
|
private readonly options;
|
|
583
691
|
private readonly connection;
|
|
584
692
|
private readonly logger;
|
|
693
|
+
private readonly migration;
|
|
585
694
|
constructor(options: JetstreamModuleOptions, connection: ConnectionProvider);
|
|
586
695
|
/**
|
|
587
696
|
* Ensure all required streams exist with correct configuration.
|
|
588
697
|
*
|
|
589
698
|
* @param kinds Which stream kinds to create. Determined by the module based
|
|
590
699
|
* on RPC mode and registered handler patterns.
|
|
700
|
+
* If the dlq option is enabled, also ensures the DLQ stream exists.
|
|
591
701
|
*/
|
|
592
702
|
ensureStreams(kinds: StreamKind[]): Promise<void>;
|
|
593
703
|
/** Get the stream name for a given kind. */
|
|
@@ -596,14 +706,32 @@ declare class StreamProvider {
|
|
|
596
706
|
getSubjects(kind: StreamKind): string[];
|
|
597
707
|
/** Ensure a single stream exists, creating or updating as needed. */
|
|
598
708
|
private ensureStream;
|
|
709
|
+
/** Ensure a dead-letter queue stream exists, creating or updating as needed. */
|
|
710
|
+
private ensureDlqStream;
|
|
711
|
+
private handleExistingStream;
|
|
712
|
+
private buildMutableOnlyConfig;
|
|
713
|
+
private logChanges;
|
|
599
714
|
/** Build the full stream config by merging defaults with user overrides. */
|
|
600
715
|
private buildConfig;
|
|
716
|
+
/**
|
|
717
|
+
* Build the stream configuration for the Dead-Letter Queue (DLQ).
|
|
718
|
+
*
|
|
719
|
+
* Merges the library default DLQ config with user-provided overrides.
|
|
720
|
+
* Ensures transport-controlled settings like retention are safely decoupled.
|
|
721
|
+
*/
|
|
722
|
+
private buildDlqConfig;
|
|
601
723
|
/** Get default config for a stream kind. */
|
|
602
724
|
private getDefaults;
|
|
603
725
|
/** Check if scheduling is enabled for a stream kind via `allow_msg_schedules` override. */
|
|
604
726
|
private isSchedulingEnabled;
|
|
605
|
-
/** Get user-provided overrides for a stream kind. */
|
|
727
|
+
/** Get user-provided overrides for a stream kind, stripping transport-controlled properties. */
|
|
606
728
|
private getOverrides;
|
|
729
|
+
/**
|
|
730
|
+
* Remove transport-controlled properties from user overrides.
|
|
731
|
+
* `retention` is managed by the transport (Workqueue/Limits per stream kind)
|
|
732
|
+
* and silently stripped to protect users from misconfiguration.
|
|
733
|
+
*/
|
|
734
|
+
private stripTransportControlled;
|
|
607
735
|
}
|
|
608
736
|
|
|
609
737
|
/**
|
|
@@ -615,6 +743,11 @@ declare class StreamProvider {
|
|
|
615
743
|
* **Ordered** — strict sequential delivery:
|
|
616
744
|
* - No ack/nak/DLQ — nats.js auto-acknowledges ordered consumer messages.
|
|
617
745
|
* - Handler errors are logged but do not affect delivery.
|
|
746
|
+
*
|
|
747
|
+
* **Dead-Letter Queue (DLQ) - for handling failed message deliveries**
|
|
748
|
+
* - If `options.dlq` is configured, messages that exhaust their max delivery attempts are published to a DLQ stream.
|
|
749
|
+
* - The DLQ stream name is derived from the service name (e.g., `orders__microservice_dlq-stream`).
|
|
750
|
+
* - Original message data and metadata are preserved in the DLQ message, with additional headers indicating the reason for failure.
|
|
618
751
|
*/
|
|
619
752
|
declare class EventRouter {
|
|
620
753
|
private readonly messageProvider;
|
|
@@ -624,9 +757,11 @@ declare class EventRouter {
|
|
|
624
757
|
private readonly deadLetterConfig?;
|
|
625
758
|
private readonly processingConfig?;
|
|
626
759
|
private readonly ackWaitMap?;
|
|
760
|
+
private readonly connection?;
|
|
761
|
+
private readonly options?;
|
|
627
762
|
private readonly logger;
|
|
628
763
|
private readonly subscriptions;
|
|
629
|
-
constructor(messageProvider: MessageProvider, patternRegistry: PatternRegistry, codec: Codec, eventBus: EventBus, deadLetterConfig?: DeadLetterConfig | undefined, processingConfig?: EventProcessingConfig | undefined, ackWaitMap?: Map<StreamKind, number> | undefined);
|
|
764
|
+
constructor(messageProvider: MessageProvider, patternRegistry: PatternRegistry, codec: Codec, eventBus: EventBus, deadLetterConfig?: DeadLetterConfig | undefined, processingConfig?: EventProcessingConfig | undefined, ackWaitMap?: Map<StreamKind, number> | undefined, connection?: ConnectionProvider | undefined, options?: JetstreamModuleOptions | undefined);
|
|
630
765
|
/**
|
|
631
766
|
* Update the max_deliver thresholds from actual NATS consumer configs.
|
|
632
767
|
* Called after consumers are ensured so the DLQ map reflects reality.
|
|
@@ -636,21 +771,35 @@ declare class EventRouter {
|
|
|
636
771
|
start(): void;
|
|
637
772
|
/** Stop routing and unsubscribe from all streams. */
|
|
638
773
|
destroy(): void;
|
|
639
|
-
/** Subscribe to a message stream and route each message. */
|
|
774
|
+
/** Subscribe to a message stream and route each message to its handler. */
|
|
640
775
|
private subscribeToStream;
|
|
641
776
|
private getConcurrency;
|
|
642
777
|
private getAckExtensionConfig;
|
|
643
|
-
/** Handle a single event message with error isolation. */
|
|
644
|
-
private handleSafe;
|
|
645
|
-
/** Handle an ordered message with error isolation. */
|
|
646
|
-
private handleOrderedSafe;
|
|
647
|
-
/** Resolve handler, decode payload, and build context. Returns null on failure. */
|
|
648
|
-
private decodeMessage;
|
|
649
|
-
/** Execute handler, then ack on success or nak/dead-letter on failure. */
|
|
650
|
-
private executeHandler;
|
|
651
|
-
/** Check if the message has exhausted all delivery attempts. */
|
|
652
|
-
private isDeadLetter;
|
|
653
778
|
/** Handle a dead letter: invoke callback, then term or nak based on result. */
|
|
779
|
+
/**
|
|
780
|
+
* Fallback execution for a dead letter when DLQ is disabled, or when
|
|
781
|
+
* publishing to the DLQ stream fails (due to network or NATS errors).
|
|
782
|
+
*
|
|
783
|
+
* Triggers the user-provided `onDeadLetter` hook for logging/alerting.
|
|
784
|
+
* On success, terminates the message. On error, leaves it unacknowledged (nak)
|
|
785
|
+
* so NATS can retry the delivery on the next cycle.
|
|
786
|
+
*/
|
|
787
|
+
private fallbackToOnDeadLetterCallback;
|
|
788
|
+
/**
|
|
789
|
+
* Publish a dead letter to the configured Dead-Letter Queue (DLQ) stream.
|
|
790
|
+
*
|
|
791
|
+
* Appends diagnostic metadata headers to the original message and preserves
|
|
792
|
+
* the primary payload. If publishing succeeds, it notifies the standard
|
|
793
|
+
* `onDeadLetter` callback and terminates the message. If it fails, it falls
|
|
794
|
+
* back to the callback entirely to prevent silent data loss.
|
|
795
|
+
*/
|
|
796
|
+
private publishToDlq;
|
|
797
|
+
/**
|
|
798
|
+
* Orchestrates the handling of a message that has exhausted delivery limits.
|
|
799
|
+
*
|
|
800
|
+
* Emits a system event and delegates either to the robust DLQ stream publisher
|
|
801
|
+
* or directly to the fallback callback based on the active module configuration.
|
|
802
|
+
*/
|
|
654
803
|
private handleDeadLetter;
|
|
655
804
|
}
|
|
656
805
|
|
|
@@ -687,10 +836,6 @@ declare class RpcRouter {
|
|
|
687
836
|
start(): Promise<void>;
|
|
688
837
|
/** Stop routing and unsubscribe. */
|
|
689
838
|
destroy(): void;
|
|
690
|
-
/** Handle a single RPC command message with error isolation. */
|
|
691
|
-
private handleSafe;
|
|
692
|
-
/** Execute handler, publish response, settle message. */
|
|
693
|
-
private executeHandler;
|
|
694
839
|
}
|
|
695
840
|
|
|
696
841
|
/**
|
|
@@ -714,8 +859,36 @@ declare class ConsumerProvider {
|
|
|
714
859
|
ensureConsumers(kinds: StreamKind[]): Promise<Map<StreamKind, ConsumerInfo>>;
|
|
715
860
|
/** Get the consumer name for a given kind. */
|
|
716
861
|
getConsumerName(kind: StreamKind): string;
|
|
717
|
-
/**
|
|
718
|
-
|
|
862
|
+
/**
|
|
863
|
+
* Ensure a single consumer exists with the desired config.
|
|
864
|
+
* Used at **startup** — creates or updates the consumer to match
|
|
865
|
+
* the current pod's configuration.
|
|
866
|
+
*/
|
|
867
|
+
ensureConsumer(jsm: Awaited<ReturnType<ConnectionProvider['getJetStreamManager']>>, kind: StreamKind): Promise<ConsumerInfo>;
|
|
868
|
+
/**
|
|
869
|
+
* Recover a consumer that disappeared during runtime.
|
|
870
|
+
* Used by **self-healing** — creates if missing, but NEVER updates config.
|
|
871
|
+
*
|
|
872
|
+
* If a migration backup stream exists, another pod is mid-migration — we
|
|
873
|
+
* throw so the self-healing retry loop waits with backoff until migration
|
|
874
|
+
* completes and the backup is cleaned up.
|
|
875
|
+
*
|
|
876
|
+
* This prevents old pods from:
|
|
877
|
+
* - Overwriting a newer pod's consumer config during rolling updates
|
|
878
|
+
* - Creating consumers during migration (which would consume and delete
|
|
879
|
+
* workqueue messages while they're being restored)
|
|
880
|
+
*/
|
|
881
|
+
recoverConsumer(jsm: Awaited<ReturnType<ConnectionProvider['getJetStreamManager']>>, kind: StreamKind): Promise<ConsumerInfo>;
|
|
882
|
+
/**
|
|
883
|
+
* Throw if a migration backup stream exists for this stream.
|
|
884
|
+
* The self-healing retry loop catches the error and retries with backoff,
|
|
885
|
+
* naturally waiting until the migrating pod finishes and cleans up the backup.
|
|
886
|
+
*/
|
|
887
|
+
private assertNoMigrationInProgress;
|
|
888
|
+
/**
|
|
889
|
+
* Create a consumer, handling the race where another pod creates it first.
|
|
890
|
+
*/
|
|
891
|
+
private createConsumer;
|
|
719
892
|
/** Build consumer config by merging defaults with user overrides. */
|
|
720
893
|
private buildConfig;
|
|
721
894
|
/** Get default config for a consumer kind. */
|
|
@@ -724,6 +897,8 @@ declare class ConsumerProvider {
|
|
|
724
897
|
private getOverrides;
|
|
725
898
|
}
|
|
726
899
|
|
|
900
|
+
/** Callback to recreate a consumer when it disappears. */
|
|
901
|
+
type ConsumerRecoveryFn = (kind: StreamKind) => Promise<ConsumerInfo>;
|
|
727
902
|
/**
|
|
728
903
|
* Manages pull-based message consumption from JetStream consumers.
|
|
729
904
|
*
|
|
@@ -737,6 +912,7 @@ declare class MessageProvider {
|
|
|
737
912
|
private readonly connection;
|
|
738
913
|
private readonly eventBus;
|
|
739
914
|
private readonly consumeOptionsMap;
|
|
915
|
+
private readonly consumerRecoveryFn?;
|
|
740
916
|
private readonly logger;
|
|
741
917
|
private readonly activeIterators;
|
|
742
918
|
private orderedReadyResolve;
|
|
@@ -746,7 +922,7 @@ declare class MessageProvider {
|
|
|
746
922
|
private commandMessages$;
|
|
747
923
|
private broadcastMessages$;
|
|
748
924
|
private orderedMessages$;
|
|
749
|
-
constructor(connection: ConnectionProvider, eventBus: EventBus, consumeOptionsMap?: Map<StreamKind, Partial<ConsumeOptions
|
|
925
|
+
constructor(connection: ConnectionProvider, eventBus: EventBus, consumeOptionsMap?: Map<StreamKind, Partial<ConsumeOptions>>, consumerRecoveryFn?: ConsumerRecoveryFn | undefined);
|
|
750
926
|
/** Observable stream of workqueue event messages. */
|
|
751
927
|
get events$(): Observable<JsMsg>;
|
|
752
928
|
/** Observable stream of RPC command messages (jetstream mode). */
|
|
@@ -779,6 +955,14 @@ declare class MessageProvider {
|
|
|
779
955
|
private createFlow;
|
|
780
956
|
/** Single iteration: get consumer -> pull messages -> emit to subject. */
|
|
781
957
|
private consumeOnce;
|
|
958
|
+
/**
|
|
959
|
+
* Detect "consumer not found" errors from `js.consumers.get()`.
|
|
960
|
+
*
|
|
961
|
+
* Unlike JetStream Manager calls (which throw `JetStreamApiError`),
|
|
962
|
+
* the JetStream client's `consumers.get()` throws a plain `Error`
|
|
963
|
+
* with the error code embedded in the message text.
|
|
964
|
+
*/
|
|
965
|
+
private isConsumerNotFound;
|
|
782
966
|
/** Get the target subject for a consumer kind. */
|
|
783
967
|
private getTargetSubject;
|
|
784
968
|
/** Monitor heartbeats and restart the consumer iterator on prolonged silence. */
|
|
@@ -787,10 +971,76 @@ declare class MessageProvider {
|
|
|
787
971
|
private createOrderedFlow;
|
|
788
972
|
/** Shared self-healing flow: defer -> retry with exponential backoff on error/completion. */
|
|
789
973
|
private createSelfHealingFlow;
|
|
790
|
-
/** Single iteration: create ordered consumer ->
|
|
974
|
+
/** Single iteration: create ordered consumer -> push messages into the subject. */
|
|
791
975
|
private consumeOrderedOnce;
|
|
792
976
|
}
|
|
793
977
|
|
|
978
|
+
/**
|
|
979
|
+
* Publishes handler metadata to a NATS KV bucket for external service discovery.
|
|
980
|
+
*
|
|
981
|
+
* Uses TTL + heartbeat to manage entry lifecycle:
|
|
982
|
+
* - Entries are written on startup and refreshed every `ttl / 2`
|
|
983
|
+
* - When the pod stops (graceful or crash), heartbeat stops → entries expire via TTL
|
|
984
|
+
* - No explicit delete needed — NATS handles expiry automatically
|
|
985
|
+
*
|
|
986
|
+
* This provider is fully decoupled from stream/consumer infrastructure —
|
|
987
|
+
* it only depends on the NATS connection and module options.
|
|
988
|
+
*/
|
|
989
|
+
declare class MetadataProvider {
|
|
990
|
+
private readonly connection;
|
|
991
|
+
private readonly logger;
|
|
992
|
+
private readonly bucketName;
|
|
993
|
+
private readonly replicas;
|
|
994
|
+
private readonly ttl;
|
|
995
|
+
private currentEntries?;
|
|
996
|
+
private heartbeatTimer?;
|
|
997
|
+
private cachedKv?;
|
|
998
|
+
constructor(options: JetstreamModuleOptions, connection: ConnectionProvider);
|
|
999
|
+
/**
|
|
1000
|
+
* Write handler metadata entries to the KV bucket and start heartbeat.
|
|
1001
|
+
*
|
|
1002
|
+
* Creates the bucket if it doesn't exist (idempotent).
|
|
1003
|
+
* Skips silently when entries map is empty.
|
|
1004
|
+
* Starts a heartbeat interval that refreshes entries every `ttl / 2`
|
|
1005
|
+
* to prevent TTL expiry while the pod is alive.
|
|
1006
|
+
*
|
|
1007
|
+
* Non-critical — errors are logged but do not prevent transport startup.
|
|
1008
|
+
*
|
|
1009
|
+
* @param entries Map of KV key → metadata object.
|
|
1010
|
+
*/
|
|
1011
|
+
publish(entries: Map<string, Record<string, unknown>>): Promise<void>;
|
|
1012
|
+
/**
|
|
1013
|
+
* Stop the heartbeat timer.
|
|
1014
|
+
*
|
|
1015
|
+
* After this call, entries will expire via TTL once the heartbeat window passes.
|
|
1016
|
+
* Called during transport shutdown (strategy.close()).
|
|
1017
|
+
*/
|
|
1018
|
+
destroy(): void;
|
|
1019
|
+
/** Write entries to KV with per-entry error handling. */
|
|
1020
|
+
private writeEntries;
|
|
1021
|
+
/** Start heartbeat interval that refreshes entries every ttl/2. */
|
|
1022
|
+
private startHeartbeat;
|
|
1023
|
+
/** Refresh all current entries in KV (heartbeat tick). */
|
|
1024
|
+
private refreshEntries;
|
|
1025
|
+
/** Create or open the KV bucket (cached after first call). */
|
|
1026
|
+
private openBucket;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
/**
|
|
1030
|
+
* NATS JetStream API error codes used by the transport.
|
|
1031
|
+
*
|
|
1032
|
+
* Ref: https://github.com/nats-io/nats-server (server error definitions)
|
|
1033
|
+
* Verified on NATS 2.12.6 via integration tests (2026-04-02).
|
|
1034
|
+
*/
|
|
1035
|
+
declare enum NatsErrorCode {
|
|
1036
|
+
/** Consumer does not exist on the specified stream. */
|
|
1037
|
+
ConsumerNotFound = 10014,
|
|
1038
|
+
/** Consumer name already in use with different configuration (race condition on create). */
|
|
1039
|
+
ConsumerAlreadyExists = 10148,
|
|
1040
|
+
/** Stream does not exist. */
|
|
1041
|
+
StreamNotFound = 10059
|
|
1042
|
+
}
|
|
1043
|
+
|
|
794
1044
|
/**
|
|
795
1045
|
* NestJS custom transport strategy for NATS JetStream.
|
|
796
1046
|
*
|
|
@@ -813,17 +1063,18 @@ declare class JetstreamStrategy extends Server implements CustomTransportStrateg
|
|
|
813
1063
|
private readonly rpcRouter;
|
|
814
1064
|
private readonly coreRpcServer;
|
|
815
1065
|
private readonly ackWaitMap;
|
|
1066
|
+
private readonly metadataProvider?;
|
|
816
1067
|
readonly transportId: symbol;
|
|
817
1068
|
private readonly listeners;
|
|
818
1069
|
private started;
|
|
819
|
-
constructor(options: JetstreamModuleOptions, connection: ConnectionProvider, patternRegistry: PatternRegistry, streamProvider: StreamProvider, consumerProvider: ConsumerProvider, messageProvider: MessageProvider, eventRouter: EventRouter, rpcRouter: RpcRouter, coreRpcServer: CoreRpcServer, ackWaitMap?: Map<StreamKind, number
|
|
1070
|
+
constructor(options: JetstreamModuleOptions, connection: ConnectionProvider, patternRegistry: PatternRegistry, streamProvider: StreamProvider, consumerProvider: ConsumerProvider, messageProvider: MessageProvider, eventRouter: EventRouter, rpcRouter: RpcRouter, coreRpcServer: CoreRpcServer, ackWaitMap?: Map<StreamKind, number>, metadataProvider?: MetadataProvider | undefined);
|
|
820
1071
|
/**
|
|
821
1072
|
* Start the transport: register handlers, create infrastructure, begin consumption.
|
|
822
1073
|
*
|
|
823
1074
|
* Called by NestJS when `connectMicroservice()` is used, or internally by the module.
|
|
824
1075
|
*/
|
|
825
1076
|
listen(callback: () => void): Promise<void>;
|
|
826
|
-
/** Stop all consumers, routers, and
|
|
1077
|
+
/** Stop all consumers, routers, subscriptions, and metadata heartbeat. Called during shutdown. */
|
|
827
1078
|
close(): void;
|
|
828
1079
|
/**
|
|
829
1080
|
* Register event listener (required by Server base class).
|
|
@@ -858,22 +1109,30 @@ interface Stoppable {
|
|
|
858
1109
|
* Shutdown sequence:
|
|
859
1110
|
* 1. Emit onShutdownStart hook
|
|
860
1111
|
* 2. Stop accepting new messages (close subscriptions, stop consumers)
|
|
861
|
-
* 3.
|
|
862
|
-
* 4.
|
|
863
|
-
*
|
|
1112
|
+
* 3. Drain and close NATS connection (with timeout safety net)
|
|
1113
|
+
* 4. Emit onShutdownComplete hook
|
|
1114
|
+
*
|
|
1115
|
+
* Idempotent — concurrent or repeated calls return the same promise.
|
|
1116
|
+
* This is critical because NestJS may call `onApplicationShutdown` on
|
|
1117
|
+
* multiple module instances (forRoot + forFeature) that share this
|
|
1118
|
+
* singleton, and the call order is not guaranteed.
|
|
864
1119
|
*/
|
|
865
1120
|
declare class ShutdownManager {
|
|
866
1121
|
private readonly connection;
|
|
867
1122
|
private readonly eventBus;
|
|
868
1123
|
private readonly timeout;
|
|
869
1124
|
private readonly logger;
|
|
1125
|
+
private shutdownPromise?;
|
|
870
1126
|
constructor(connection: ConnectionProvider, eventBus: EventBus, timeout: number);
|
|
871
1127
|
/**
|
|
872
1128
|
* Execute the full shutdown sequence.
|
|
873
1129
|
*
|
|
1130
|
+
* Idempotent — concurrent or repeated calls return the same promise.
|
|
1131
|
+
*
|
|
874
1132
|
* @param strategy Optional stoppable to close (stops consumers and subscriptions).
|
|
875
1133
|
*/
|
|
876
1134
|
shutdown(strategy?: Stoppable): Promise<void>;
|
|
1135
|
+
private doShutdown;
|
|
877
1136
|
}
|
|
878
1137
|
|
|
879
1138
|
/**
|
|
@@ -976,6 +1235,21 @@ declare class JetstreamClient extends ClientProxy {
|
|
|
976
1235
|
private readonly targetName;
|
|
977
1236
|
/** Pre-cached caller name derived from rootOptions.name, computed once in constructor. */
|
|
978
1237
|
private readonly callerName;
|
|
1238
|
+
/**
|
|
1239
|
+
* Subject prefixes of the form `{serviceName}__microservice.{kind}.` — one
|
|
1240
|
+
* per stream kind this client may publish to. Built once in the constructor
|
|
1241
|
+
* so producing a full subject is a single string concat with the user pattern.
|
|
1242
|
+
*/
|
|
1243
|
+
private readonly eventSubjectPrefix;
|
|
1244
|
+
private readonly commandSubjectPrefix;
|
|
1245
|
+
private readonly orderedSubjectPrefix;
|
|
1246
|
+
/**
|
|
1247
|
+
* RPC configuration snapshots. The values are derived from rootOptions at
|
|
1248
|
+
* construction time so the publish hot path never has to re-run
|
|
1249
|
+
* isCoreRpcMode / getRpcTimeout on every call.
|
|
1250
|
+
*/
|
|
1251
|
+
private readonly isCoreMode;
|
|
1252
|
+
private readonly defaultRpcTimeout;
|
|
979
1253
|
/** Shared inbox for JetStream-mode RPC responses. */
|
|
980
1254
|
private inbox;
|
|
981
1255
|
private inboxSubscription;
|
|
@@ -985,6 +1259,12 @@ declare class JetstreamClient extends ClientProxy {
|
|
|
985
1259
|
private readonly pendingTimeouts;
|
|
986
1260
|
/** Subscription to connection status events for disconnect handling. */
|
|
987
1261
|
private statusSubscription;
|
|
1262
|
+
/**
|
|
1263
|
+
* Cached readiness flag. Once `connect()` has wired the inbox and status
|
|
1264
|
+
* subscription, subsequent publishes skip the `await connect()` microtask
|
|
1265
|
+
* and reach for the underlying connection synchronously instead.
|
|
1266
|
+
*/
|
|
1267
|
+
private readyForPublish;
|
|
988
1268
|
constructor(rootOptions: JetstreamModuleOptions, targetServiceName: string, connection: ConnectionProvider, codec: Codec, eventBus: EventBus);
|
|
989
1269
|
/**
|
|
990
1270
|
* Establish connection. Called automatically by NestJS on first use.
|
|
@@ -1031,7 +1311,14 @@ declare class JetstreamClient extends ClientProxy {
|
|
|
1031
1311
|
private setupInbox;
|
|
1032
1312
|
/** Route an inbox reply to the matching pending callback. */
|
|
1033
1313
|
private routeInboxReply;
|
|
1034
|
-
/**
|
|
1314
|
+
/**
|
|
1315
|
+
* Resolve a user pattern to a fully-qualified NATS subject, dispatching
|
|
1316
|
+
* between the event, broadcast, and ordered prefixes.
|
|
1317
|
+
*
|
|
1318
|
+
* The leading-char check short-circuits the `startsWith` comparisons for
|
|
1319
|
+
* patterns that cannot possibly carry a broadcast/ordered marker, which is
|
|
1320
|
+
* the overwhelmingly common case.
|
|
1321
|
+
*/
|
|
1035
1322
|
private buildEventSubject;
|
|
1036
1323
|
/** Build NATS headers merging custom headers with transport headers. */
|
|
1037
1324
|
private buildHeaders;
|
|
@@ -1049,7 +1336,6 @@ declare class JetstreamClient extends ClientProxy {
|
|
|
1049
1336
|
* - `broadcast.config.updated` → `broadcast._sch.config.updated`
|
|
1050
1337
|
*/
|
|
1051
1338
|
private buildScheduleSubject;
|
|
1052
|
-
private getRpcTimeout;
|
|
1053
1339
|
}
|
|
1054
1340
|
|
|
1055
1341
|
/**
|
|
@@ -1079,6 +1365,8 @@ declare class JetstreamRecord<TData = unknown> {
|
|
|
1079
1365
|
readonly messageId?: string | undefined;
|
|
1080
1366
|
/** Schedule options for delayed delivery. */
|
|
1081
1367
|
readonly schedule?: ScheduleRecordOptions | undefined;
|
|
1368
|
+
/** Per-message TTL as Go duration string (e.g. "30s", "5m"). */
|
|
1369
|
+
readonly ttl?: string | undefined;
|
|
1082
1370
|
constructor(
|
|
1083
1371
|
/** Message payload. */
|
|
1084
1372
|
data: TData,
|
|
@@ -1089,7 +1377,9 @@ declare class JetstreamRecord<TData = unknown> {
|
|
|
1089
1377
|
/** Custom message ID for JetStream deduplication. */
|
|
1090
1378
|
messageId?: string | undefined,
|
|
1091
1379
|
/** Schedule options for delayed delivery. */
|
|
1092
|
-
schedule?: ScheduleRecordOptions | undefined
|
|
1380
|
+
schedule?: ScheduleRecordOptions | undefined,
|
|
1381
|
+
/** Per-message TTL as Go duration string (e.g. "30s", "5m"). */
|
|
1382
|
+
ttl?: string | undefined);
|
|
1093
1383
|
}
|
|
1094
1384
|
/**
|
|
1095
1385
|
* Fluent builder for constructing JetstreamRecord instances.
|
|
@@ -1103,6 +1393,7 @@ declare class JetstreamRecordBuilder<TData = unknown> {
|
|
|
1103
1393
|
private timeout;
|
|
1104
1394
|
private messageId;
|
|
1105
1395
|
private scheduleOptions;
|
|
1396
|
+
private ttlDuration;
|
|
1106
1397
|
constructor(data?: TData);
|
|
1107
1398
|
/**
|
|
1108
1399
|
* Set the message payload.
|
|
@@ -1164,6 +1455,27 @@ declare class JetstreamRecordBuilder<TData = unknown> {
|
|
|
1164
1455
|
* @throws Error if the date is not in the future.
|
|
1165
1456
|
*/
|
|
1166
1457
|
scheduleAt(date: Date): this;
|
|
1458
|
+
/**
|
|
1459
|
+
* Set per-message TTL (time-to-live).
|
|
1460
|
+
*
|
|
1461
|
+
* The message expires individually after the specified duration,
|
|
1462
|
+
* independent of the stream's `max_age`. Requires NATS >= 2.11 and
|
|
1463
|
+
* `allow_msg_ttl: true` on the stream.
|
|
1464
|
+
*
|
|
1465
|
+
* Only meaningful for events (`client.emit()`). If used with RPC
|
|
1466
|
+
* (`client.send()`), a warning is logged and the TTL is ignored.
|
|
1467
|
+
*
|
|
1468
|
+
* @param nanos - TTL in nanoseconds. Use {@link toNanos} for human-readable values.
|
|
1469
|
+
*
|
|
1470
|
+
* @example
|
|
1471
|
+
* ```typescript
|
|
1472
|
+
* import { toNanos } from '@horizon-republic/nestjs-jetstream';
|
|
1473
|
+
*
|
|
1474
|
+
* new JetstreamRecordBuilder(payload).ttl(toNanos(30, 'minutes')).build();
|
|
1475
|
+
* new JetstreamRecordBuilder(payload).ttl(toNanos(24, 'hours')).build();
|
|
1476
|
+
* ```
|
|
1477
|
+
*/
|
|
1478
|
+
ttl(nanos: number): this;
|
|
1167
1479
|
/**
|
|
1168
1480
|
* Build the immutable {@link JetstreamRecord}.
|
|
1169
1481
|
*
|
|
@@ -1192,6 +1504,52 @@ declare class JsonCodec implements Codec {
|
|
|
1192
1504
|
decode(data: Uint8Array): unknown;
|
|
1193
1505
|
}
|
|
1194
1506
|
|
|
1507
|
+
/**
|
|
1508
|
+
* Minimal shape of a `msgpackr` `Packr` instance used by {@link MsgpackCodec}.
|
|
1509
|
+
*
|
|
1510
|
+
* Typed locally so consumers who do not use MessagePack encoding never pay
|
|
1511
|
+
* for a `msgpackr` import.
|
|
1512
|
+
*/
|
|
1513
|
+
interface PackrLike {
|
|
1514
|
+
pack(data: unknown): Uint8Array;
|
|
1515
|
+
unpack(data: Uint8Array): unknown;
|
|
1516
|
+
}
|
|
1517
|
+
/**
|
|
1518
|
+
* MessagePack codec backed by a caller-provided `msgpackr` `Packr` instance.
|
|
1519
|
+
*
|
|
1520
|
+
* Use this codec when publishing structured payloads larger than roughly
|
|
1521
|
+
* 1–2 KB — below that size the default {@link JsonCodec} wins on per-call
|
|
1522
|
+
* constant overhead. Above it, MessagePack encodes and decodes several times
|
|
1523
|
+
* faster and produces smaller wire frames. The format is cross-language, so
|
|
1524
|
+
* Node producers and non-Node consumers (Python, Go, Java, Rust, ...) stay
|
|
1525
|
+
* interoperable.
|
|
1526
|
+
*
|
|
1527
|
+
* Requires installing the optional `msgpackr` peer dependency:
|
|
1528
|
+
*
|
|
1529
|
+
* ```bash
|
|
1530
|
+
* npm install msgpackr
|
|
1531
|
+
* # or: pnpm add msgpackr
|
|
1532
|
+
* ```
|
|
1533
|
+
*
|
|
1534
|
+
* @example
|
|
1535
|
+
* ```typescript
|
|
1536
|
+
* import { JetstreamModule, MsgpackCodec } from '@horizon-republic/nestjs-jetstream';
|
|
1537
|
+
* import { Packr } from 'msgpackr';
|
|
1538
|
+
*
|
|
1539
|
+
* JetstreamModule.forRoot({
|
|
1540
|
+
* name: 'orders',
|
|
1541
|
+
* servers: ['nats://localhost:4222'],
|
|
1542
|
+
* codec: new MsgpackCodec(new Packr()),
|
|
1543
|
+
* });
|
|
1544
|
+
* ```
|
|
1545
|
+
*/
|
|
1546
|
+
declare class MsgpackCodec implements Codec {
|
|
1547
|
+
private readonly packr;
|
|
1548
|
+
constructor(packr: PackrLike);
|
|
1549
|
+
encode(data: unknown): Uint8Array;
|
|
1550
|
+
decode(data: Uint8Array): unknown;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1195
1553
|
type NatsMessage = JsMsg | Msg;
|
|
1196
1554
|
/**
|
|
1197
1555
|
* Execution context for RPC and event handlers.
|
|
@@ -1212,7 +1570,7 @@ type NatsMessage = JsMsg | Msg;
|
|
|
1212
1570
|
* return;
|
|
1213
1571
|
* }
|
|
1214
1572
|
* if (!this.isReady()) {
|
|
1215
|
-
* ctx.retry({
|
|
1573
|
+
* ctx.retry({ delayMs: 5000 });
|
|
1216
1574
|
* return;
|
|
1217
1575
|
* }
|
|
1218
1576
|
* await this.process(data);
|
|
@@ -1330,9 +1688,14 @@ declare class JetstreamHealthIndicator {
|
|
|
1330
1688
|
* Returns `{ [key]: { status: 'up', ... } }` on success.
|
|
1331
1689
|
* Throws an error with `{ [key]: { status: 'down', ... } }` on failure.
|
|
1332
1690
|
*
|
|
1691
|
+
* The thrown error sets `isHealthCheckError: true` and `causes` — the
|
|
1692
|
+
* duck-type contract that Terminus `HealthCheckExecutor` uses to distinguish
|
|
1693
|
+
* health failures from unexpected exceptions. Works with both Terminus v10
|
|
1694
|
+
* (`instanceof HealthCheckError`) and v11+ (`error?.isHealthCheckError`).
|
|
1695
|
+
*
|
|
1333
1696
|
* @param key - Health indicator key (default: `'jetstream'`).
|
|
1334
1697
|
* @returns Object with status, server, and latency under the given key.
|
|
1335
|
-
* @throws Error with `{ [key]: { status: 'down' } }
|
|
1698
|
+
* @throws Error with `isHealthCheckError`, `causes`, and `{ [key]: { status: 'down' } }`.
|
|
1336
1699
|
*/
|
|
1337
1700
|
isHealthy(key?: string): Promise<Record<string, Record<string, unknown>>>;
|
|
1338
1701
|
}
|
|
@@ -1343,8 +1706,6 @@ declare const JETSTREAM_OPTIONS: unique symbol;
|
|
|
1343
1706
|
declare const JETSTREAM_CONNECTION: unique symbol;
|
|
1344
1707
|
/** Token for the global Codec instance. */
|
|
1345
1708
|
declare const JETSTREAM_CODEC: unique symbol;
|
|
1346
|
-
/** Token for the EventBus instance. */
|
|
1347
|
-
declare const JETSTREAM_EVENT_BUS: unique symbol;
|
|
1348
1709
|
/**
|
|
1349
1710
|
* Generate the injection token for a `forFeature()` client.
|
|
1350
1711
|
*
|
|
@@ -1377,6 +1738,47 @@ type TimeUnit = 'ms' | 'seconds' | 'minutes' | 'hours' | 'days';
|
|
|
1377
1738
|
* ```
|
|
1378
1739
|
*/
|
|
1379
1740
|
declare const toNanos: (value: number, unit: TimeUnit) => number;
|
|
1741
|
+
/** Default config for workqueue event streams. */
|
|
1742
|
+
declare const DEFAULT_EVENT_STREAM_CONFIG: Partial<StreamConfig>;
|
|
1743
|
+
/** Default config for RPC command streams (jetstream mode only). */
|
|
1744
|
+
declare const DEFAULT_COMMAND_STREAM_CONFIG: Partial<StreamConfig>;
|
|
1745
|
+
/** Default config for broadcast event streams. */
|
|
1746
|
+
declare const DEFAULT_BROADCAST_STREAM_CONFIG: Partial<StreamConfig>;
|
|
1747
|
+
/** Default config for ordered event streams (Limits retention). */
|
|
1748
|
+
declare const DEFAULT_ORDERED_STREAM_CONFIG: Partial<StreamConfig>;
|
|
1749
|
+
/** Default config for dead-letter queue (DLQ) streams. */
|
|
1750
|
+
declare const DEFAULT_DLQ_STREAM_CONFIG: Partial<StreamConfig>;
|
|
1751
|
+
/** Default config for workqueue event consumers. */
|
|
1752
|
+
declare const DEFAULT_EVENT_CONSUMER_CONFIG: Partial<ConsumerConfig>;
|
|
1753
|
+
/** Default config for RPC command consumers (jetstream mode only). */
|
|
1754
|
+
declare const DEFAULT_COMMAND_CONSUMER_CONFIG: Partial<ConsumerConfig>;
|
|
1755
|
+
/** Default config for broadcast event consumers. */
|
|
1756
|
+
declare const DEFAULT_BROADCAST_CONSUMER_CONFIG: Partial<ConsumerConfig>;
|
|
1757
|
+
/** Default RPC timeout for Core mode (30 seconds). */
|
|
1758
|
+
declare const DEFAULT_RPC_TIMEOUT = 30000;
|
|
1759
|
+
/** Default RPC timeout for JetStream mode (3 minutes). */
|
|
1760
|
+
declare const DEFAULT_JETSTREAM_RPC_TIMEOUT = 180000;
|
|
1761
|
+
/** Default graceful shutdown timeout (10 seconds). */
|
|
1762
|
+
declare const DEFAULT_SHUTDOWN_TIMEOUT = 10000;
|
|
1763
|
+
/** Default KV bucket name for handler metadata. */
|
|
1764
|
+
declare const DEFAULT_METADATA_BUCKET = "handler_registry";
|
|
1765
|
+
/** Default number of KV bucket replicas. */
|
|
1766
|
+
declare const DEFAULT_METADATA_REPLICAS = 1;
|
|
1767
|
+
/** Default KV bucket history depth (latest value only). */
|
|
1768
|
+
declare const DEFAULT_METADATA_HISTORY = 1;
|
|
1769
|
+
/** Default KV bucket TTL in milliseconds (entries expire unless refreshed). */
|
|
1770
|
+
declare const DEFAULT_METADATA_TTL = 30000;
|
|
1771
|
+
/** Minimum allowed metadata TTL in milliseconds. Prevents tight heartbeat loops. */
|
|
1772
|
+
declare const MIN_METADATA_TTL = 5000;
|
|
1773
|
+
/**
|
|
1774
|
+
* Build a KV key for a handler's metadata entry.
|
|
1775
|
+
*
|
|
1776
|
+
* @param serviceName - Service name from `forRoot({ name })`.
|
|
1777
|
+
* @param kind - Handler's stream kind ({@link StreamKind}).
|
|
1778
|
+
* @param pattern - The message pattern (e.g. `'order.created'`).
|
|
1779
|
+
* @returns KV key (e.g. `orders.ev.order.created`).
|
|
1780
|
+
*/
|
|
1781
|
+
declare const metadataKey: (serviceName: string, kind: StreamKind, pattern: string) => string;
|
|
1380
1782
|
/**
|
|
1381
1783
|
* NATS headers managed by the transport.
|
|
1382
1784
|
*
|
|
@@ -1396,6 +1798,20 @@ declare enum JetstreamHeader {
|
|
|
1396
1798
|
/** Set to `'true'` on error responses so the client can distinguish success from failure. */
|
|
1397
1799
|
Error = "x-error"
|
|
1398
1800
|
}
|
|
1801
|
+
declare enum JetstreamDlqHeader {
|
|
1802
|
+
/** Reason for the message being sent to the DLQ — the last handler error message. */
|
|
1803
|
+
DeadLetterReason = "x-dead-letter-reason",
|
|
1804
|
+
/** Original NATS subject the message was originally published to */
|
|
1805
|
+
OriginalSubject = "x-original-subject",
|
|
1806
|
+
/** Source stream name */
|
|
1807
|
+
OriginalStream = "x-original-stream",
|
|
1808
|
+
/** ISO timestamp of when the message was moved to DLQ */
|
|
1809
|
+
FailedAt = "x-failed-at",
|
|
1810
|
+
/** Number of times the message has been delivered */
|
|
1811
|
+
DeliveryCount = "x-delivery-count"
|
|
1812
|
+
}
|
|
1813
|
+
/** Set of header names that are reserved and cannot be set by users. */
|
|
1814
|
+
declare const RESERVED_HEADERS: Set<string>;
|
|
1399
1815
|
/**
|
|
1400
1816
|
* Build the internal service name with microservice suffix.
|
|
1401
1817
|
*
|
|
@@ -1412,6 +1828,13 @@ declare const internalName: (name: string) => string;
|
|
|
1412
1828
|
* @returns `{serviceName}__microservice.{kind}.{pattern}`
|
|
1413
1829
|
*/
|
|
1414
1830
|
declare const buildSubject: (serviceName: string, kind: SubjectKind, pattern: string) => string;
|
|
1831
|
+
/**
|
|
1832
|
+
* Build a broadcast subject.
|
|
1833
|
+
*
|
|
1834
|
+
* @param pattern - The message pattern (e.g. `'config.updated'`).
|
|
1835
|
+
* @returns `broadcast.{pattern}`
|
|
1836
|
+
*/
|
|
1837
|
+
declare const buildBroadcastSubject: (pattern: string) => string;
|
|
1415
1838
|
/**
|
|
1416
1839
|
* Build the JetStream stream name for a given service and kind.
|
|
1417
1840
|
*
|
|
@@ -1420,6 +1843,13 @@ declare const buildSubject: (serviceName: string, kind: SubjectKind, pattern: st
|
|
|
1420
1843
|
* @returns Stream name (e.g. `orders__microservice_ev-stream` or `broadcast-stream`).
|
|
1421
1844
|
*/
|
|
1422
1845
|
declare const streamName: (serviceName: string, kind: StreamKind) => string;
|
|
1846
|
+
/**
|
|
1847
|
+
* Build the JetStream dead-letter queue stream name for a given service.
|
|
1848
|
+
*
|
|
1849
|
+
* @param serviceName - Service name from `forRoot({ name })`.
|
|
1850
|
+
* @returns DLQ Stream name (e.g. `orders__microservice_dlq-stream`).
|
|
1851
|
+
*/
|
|
1852
|
+
declare const dlqStreamName: (serviceName: string) => string;
|
|
1423
1853
|
/**
|
|
1424
1854
|
* Build the JetStream consumer name for a given service and kind.
|
|
1425
1855
|
*
|
|
@@ -1443,4 +1873,4 @@ declare const isJetStreamRpcMode: (rpc: RpcConfig | undefined) => boolean;
|
|
|
1443
1873
|
/** Check if the RPC config specifies Core mode (default). */
|
|
1444
1874
|
declare const isCoreRpcMode: (rpc: RpcConfig | undefined) => boolean;
|
|
1445
1875
|
|
|
1446
|
-
export { type Codec, type DeadLetterInfo,
|
|
1876
|
+
export { type Codec, DEFAULT_BROADCAST_CONSUMER_CONFIG, DEFAULT_BROADCAST_STREAM_CONFIG, DEFAULT_COMMAND_CONSUMER_CONFIG, DEFAULT_COMMAND_STREAM_CONFIG, DEFAULT_DLQ_STREAM_CONFIG, DEFAULT_EVENT_CONSUMER_CONFIG, DEFAULT_EVENT_STREAM_CONFIG, DEFAULT_JETSTREAM_RPC_TIMEOUT, DEFAULT_METADATA_BUCKET, DEFAULT_METADATA_HISTORY, DEFAULT_METADATA_REPLICAS, DEFAULT_METADATA_TTL, DEFAULT_ORDERED_STREAM_CONFIG, DEFAULT_RPC_TIMEOUT, DEFAULT_SHUTDOWN_TIMEOUT, type DeadLetterInfo, JETSTREAM_CODEC, JETSTREAM_CONNECTION, JETSTREAM_OPTIONS, JetstreamClient, JetstreamDlqHeader, type JetstreamFeatureOptions, JetstreamHeader, JetstreamHealthIndicator, type JetstreamHealthStatus, JetstreamModule, type JetstreamModuleAsyncOptions, type JetstreamModuleOptions, JetstreamRecord, JetstreamRecordBuilder, JetstreamStrategy, JsonCodec, MIN_METADATA_TTL, MessageKind, type MetadataRegistryOptions, MsgpackCodec, NatsErrorCode, type OrderedEventOverrides, PatternPrefix, RESERVED_HEADERS, type RpcConfig, RpcContext, type ScheduleRecordOptions, type StreamConfigOverrides, type StreamConsumerOverrides, StreamKind, TransportEvent, type TransportHooks, buildBroadcastSubject, buildSubject, consumerName, dlqStreamName, getClientToken, internalName, isCoreRpcMode, isJetStreamRpcMode, metadataKey, streamName, toNanos };
|