@horizon-republic/nestjs-jetstream 2.9.1 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1515 -272
- package/dist/index.d.cts +965 -654
- package/dist/index.d.ts +965 -654
- package/dist/index.js +1515 -263
- package/package.json +16 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { ModuleMetadata, FactoryProvider, Type,
|
|
2
|
-
import { MsgHdrs,
|
|
3
|
-
import { StreamConfig, ConsumerConfig, ConsumeOptions, DeliverPolicy, ReplayPolicy,
|
|
4
|
-
import {
|
|
1
|
+
import { Logger, ModuleMetadata, FactoryProvider, Type, OnApplicationShutdown, DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { MsgHdrs, NatsConnection, Status, ConnectionOptions, Msg } from '@nats-io/transport-node';
|
|
3
|
+
import { JetStreamManager, JetStreamClient, StreamConfig, ConsumerConfig, ConsumeOptions, DeliverPolicy, ReplayPolicy, ConsumerInfo, JsMsg } from '@nats-io/jetstream';
|
|
4
|
+
import { Span } from '@opentelemetry/api';
|
|
5
|
+
import { ClientProxy, ReadPacket, WritePacket, MessageHandler, Server, CustomTransportStrategy, BaseRpcContext } from '@nestjs/microservices';
|
|
5
6
|
import { Observable } from 'rxjs';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -118,176 +119,859 @@ interface JetstreamHealthStatus {
|
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* (Workqueue for events/commands, Limits for broadcast/ordered).
|
|
125
|
-
* Any `retention` value provided at runtime is silently stripped.
|
|
122
|
+
* Instrumentation scope name reported on every span the library emits.
|
|
123
|
+
* Matches the npm package name — the convention used by
|
|
124
|
+
* `@opentelemetry/instrumentation-*` and most third-party instrumentations.
|
|
126
125
|
*/
|
|
127
|
-
|
|
126
|
+
declare const TRACER_NAME = "@horizon-republic/nestjs-jetstream";
|
|
127
|
+
|
|
128
128
|
/**
|
|
129
|
-
*
|
|
129
|
+
* Enumeration of OpenTelemetry trace kinds this library can emit.
|
|
130
130
|
*
|
|
131
|
-
*
|
|
132
|
-
* -
|
|
133
|
-
*
|
|
131
|
+
* Each identifier is toggleable via `otel.traces`. Functional kinds (publish,
|
|
132
|
+
* consume, RPC client round-trip, dead letter) are enabled by default;
|
|
133
|
+
* infrastructure kinds (connection lifecycle, self-healing, provisioning,
|
|
134
|
+
* migration, shutdown) are opt-in.
|
|
134
135
|
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
136
|
+
* @example
|
|
137
|
+
* JetstreamModule.forRoot({
|
|
138
|
+
* otel: {
|
|
139
|
+
* traces: [JetstreamTrace.Publish, JetstreamTrace.Consume, JetstreamTrace.ConnectionLifecycle],
|
|
140
|
+
* },
|
|
141
|
+
* })
|
|
137
142
|
*/
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
timeout?: number;
|
|
142
|
-
} | {
|
|
143
|
-
mode: 'jetstream';
|
|
144
|
-
/** Handler timeout in ms. Default: 180_000 (3 min). */
|
|
145
|
-
timeout?: number;
|
|
146
|
-
/** Raw NATS StreamConfig overrides for the command stream. */
|
|
147
|
-
stream?: StreamConfigOverrides;
|
|
148
|
-
/** Raw NATS ConsumerConfig overrides for the command consumer. */
|
|
149
|
-
consumer?: Partial<ConsumerConfig>;
|
|
150
|
-
/** Options passed to the nats.js `consumer.consume()` call for the command consumer. */
|
|
151
|
-
consume?: Partial<ConsumeOptions>;
|
|
152
|
-
/** Maximum number of concurrent RPC handler executions. */
|
|
153
|
-
concurrency?: number;
|
|
143
|
+
declare enum JetstreamTrace {
|
|
144
|
+
/** `PRODUCER` span around each `emit()` / `send()` publish operation. Default: ON. */
|
|
145
|
+
Publish = "publish",
|
|
154
146
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
147
|
+
* `CONSUMER` span around each message delivery to a handler. Retries
|
|
148
|
+
* produce separate spans with `messaging.nats.message.delivery_count > 1`.
|
|
149
|
+
* Default: ON.
|
|
157
150
|
*/
|
|
158
|
-
|
|
159
|
-
};
|
|
160
|
-
/** Overrides for JetStream stream and consumer configuration. */
|
|
161
|
-
interface StreamConsumerOverrides {
|
|
162
|
-
stream?: StreamConfigOverrides;
|
|
163
|
-
consumer?: Partial<ConsumerConfig>;
|
|
151
|
+
Consume = "consume",
|
|
164
152
|
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* nats.js supports two consumption modes (message-based and byte-based).
|
|
169
|
-
* Do not mix `max_bytes`/`threshold_bytes` with `threshold_messages` —
|
|
170
|
-
* use one mode or the other.
|
|
171
|
-
*
|
|
172
|
-
* @see https://github.com/nats-io/nats.js — ConsumeOptions
|
|
153
|
+
* `CLIENT` span covering a full RPC round-trip on the caller side
|
|
154
|
+
* (`client.send()` → reply received). Wraps the inner publish.
|
|
155
|
+
* Default: ON.
|
|
173
156
|
*/
|
|
174
|
-
|
|
157
|
+
RpcClientSend = "rpc.client.send",
|
|
175
158
|
/**
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* Default:
|
|
179
|
-
* Set this to protect downstream systems from overload.
|
|
180
|
-
*
|
|
181
|
-
* **Important:** if `concurrency < max_ack_pending`, messages buffer in RxJS
|
|
182
|
-
* while their NATS ack timer ticks. Increase `ack_wait` proportionally to
|
|
183
|
-
* prevent unnecessary redeliveries.
|
|
159
|
+
* `INTERNAL` span emitted when a message exhausts `maxDeliver` and is
|
|
160
|
+
* dead-lettered. Captures the duration of the `onDeadLetter` callback.
|
|
161
|
+
* Default: ON.
|
|
184
162
|
*/
|
|
185
|
-
|
|
163
|
+
DeadLetter = "dead_letter",
|
|
186
164
|
/**
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* - `false` (default): disabled — NATS redelivers after `ack_wait` if not acked.
|
|
190
|
-
* - `true`: auto-extend at `ack_wait / 2` interval (calculated from consumer config).
|
|
191
|
-
* - `number`: explicit extension interval in milliseconds.
|
|
165
|
+
* `INTERNAL` span spanning one NATS connection session. Emits events on
|
|
166
|
+
* connect, reconnect, disconnect. Default: OFF.
|
|
192
167
|
*/
|
|
193
|
-
|
|
168
|
+
ConnectionLifecycle = "connection.lifecycle",
|
|
169
|
+
/**
|
|
170
|
+
* `INTERNAL` span per consumer recovery attempt following a transient
|
|
171
|
+
* failure (deleted consumer, missed heartbeat). Default: OFF.
|
|
172
|
+
*/
|
|
173
|
+
SelfHealing = "self_healing",
|
|
174
|
+
/** `INTERNAL` span per stream or consumer provisioning / update at startup. Default: OFF. */
|
|
175
|
+
Provisioning = "provisioning",
|
|
176
|
+
/** `INTERNAL` span covering a destructive migration flow. Default: OFF. */
|
|
177
|
+
Migration = "migration",
|
|
178
|
+
/** `INTERNAL` span covering the graceful shutdown sequence. Default: OFF. */
|
|
179
|
+
Shutdown = "shutdown"
|
|
194
180
|
}
|
|
195
181
|
/**
|
|
196
|
-
*
|
|
182
|
+
* The set of trace kinds enabled when `otel.traces` is not configured
|
|
183
|
+
* (or set to `'default'`). Covers message-flow operations; infrastructure
|
|
184
|
+
* spans are opt-in.
|
|
185
|
+
*/
|
|
186
|
+
declare const DEFAULT_TRACES: readonly JetstreamTrace[];
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Central event bus for transport lifecycle notifications.
|
|
197
190
|
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
191
|
+
* Dispatches events to user-provided hooks. Events without a
|
|
192
|
+
* registered hook are silently ignored — no default logging.
|
|
200
193
|
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* const bus = new EventBus(logger, {
|
|
197
|
+
* [TransportEvent.Error]: (err) => sentry.captureException(err),
|
|
198
|
+
* });
|
|
199
|
+
*
|
|
200
|
+
* bus.emit(TransportEvent.Error, new Error('timeout'), 'rpc-router');
|
|
201
|
+
* // → calls sentry
|
|
202
|
+
*
|
|
203
|
+
* bus.emit(TransportEvent.Connect, 'nats://localhost:4222');
|
|
204
|
+
* // → no-op (no hook registered)
|
|
205
|
+
* ```
|
|
203
206
|
*/
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
* Where to start reading when the consumer is (re)created.
|
|
209
|
-
* @default DeliverPolicy.All
|
|
210
|
-
*/
|
|
211
|
-
deliverPolicy?: DeliverPolicy;
|
|
207
|
+
declare class EventBus {
|
|
208
|
+
private readonly hooks;
|
|
209
|
+
private readonly logger;
|
|
210
|
+
constructor(logger: Logger, hooks?: Partial<TransportHooks>);
|
|
212
211
|
/**
|
|
213
|
-
*
|
|
212
|
+
* Emit a lifecycle event. Dispatches to custom hook if registered, otherwise no-op.
|
|
213
|
+
*
|
|
214
|
+
* @param event - The {@link TransportEvent} to emit.
|
|
215
|
+
* @param args - Arguments matching the hook signature for this event.
|
|
214
216
|
*/
|
|
215
|
-
|
|
217
|
+
emit<K extends keyof TransportHooks>(event: K, ...args: Parameters<TransportHooks[K]>): void;
|
|
216
218
|
/**
|
|
217
|
-
*
|
|
219
|
+
* Hot-path optimized emit for MessageRouted events.
|
|
220
|
+
* Avoids rest/spread overhead of the generic `emit()`.
|
|
218
221
|
*/
|
|
219
|
-
|
|
222
|
+
emitMessageRouted(subject: string, kind: MessageKind): void;
|
|
220
223
|
/**
|
|
221
|
-
*
|
|
222
|
-
*
|
|
224
|
+
* Check whether a hook is registered for the given event.
|
|
225
|
+
*
|
|
226
|
+
* Used by the routing hot path to elide the emit call entirely when the
|
|
227
|
+
* transport owner did not register a listener.
|
|
223
228
|
*/
|
|
224
|
-
|
|
229
|
+
hasHook(event: keyof TransportHooks): boolean;
|
|
230
|
+
private callHook;
|
|
225
231
|
}
|
|
232
|
+
|
|
226
233
|
/**
|
|
227
|
-
*
|
|
234
|
+
* Manages the lifecycle of a single NATS connection shared across the application.
|
|
228
235
|
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
236
|
+
* Provides both Promise-based and Observable-based access to the connection:
|
|
237
|
+
* - `connect()` / `getConnection()` — async/await for one-time setup
|
|
238
|
+
* - `nc$` — cached observable (shareReplay) for reactive consumers
|
|
239
|
+
* - `status$` — live connection status event stream
|
|
232
240
|
*
|
|
233
|
-
*
|
|
241
|
+
* One instance per application, created by `JetstreamModule.forRoot()`.
|
|
234
242
|
*/
|
|
235
|
-
|
|
243
|
+
declare class ConnectionProvider {
|
|
244
|
+
private readonly options;
|
|
245
|
+
private readonly eventBus;
|
|
246
|
+
/** Cached observable that replays the established connection to new subscribers. */
|
|
247
|
+
readonly nc$: Observable<NatsConnection>;
|
|
248
|
+
/** Live stream of connection status events (no replay). */
|
|
249
|
+
readonly status$: Observable<Status>;
|
|
250
|
+
private readonly logger;
|
|
251
|
+
private connection;
|
|
252
|
+
private connectionPromise;
|
|
253
|
+
private jsClient;
|
|
254
|
+
private jsmInstance;
|
|
255
|
+
private jsmPromise;
|
|
256
|
+
private readonly otel;
|
|
257
|
+
private readonly otelServiceName;
|
|
258
|
+
private readonly otelEndpoint;
|
|
259
|
+
private lifecycleSpan;
|
|
260
|
+
constructor(options: JetstreamModuleOptions, eventBus: EventBus);
|
|
236
261
|
/**
|
|
237
|
-
*
|
|
238
|
-
*
|
|
262
|
+
* Establish NATS connection. Idempotent — returns cached connection on subsequent calls.
|
|
263
|
+
*
|
|
264
|
+
* @throws Error if connection is refused (fail fast).
|
|
239
265
|
*/
|
|
240
|
-
|
|
266
|
+
getConnection(): Promise<NatsConnection>;
|
|
241
267
|
/**
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
* @
|
|
268
|
+
* Get the JetStream manager. Cached after first call.
|
|
269
|
+
*
|
|
270
|
+
* @returns The JetStreamManager for stream/consumer administration.
|
|
245
271
|
*/
|
|
246
|
-
|
|
272
|
+
getJetStreamManager(): Promise<JetStreamManager>;
|
|
247
273
|
/**
|
|
248
|
-
*
|
|
274
|
+
* Get a cached JetStream client.
|
|
249
275
|
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* When the pod stops (graceful or crash), entries expire after this duration.
|
|
276
|
+
* Invalidated automatically on reconnect and shutdown so consumers always
|
|
277
|
+
* operate against the live connection.
|
|
253
278
|
*
|
|
254
|
-
* @
|
|
279
|
+
* @returns The cached JetStreamClient.
|
|
280
|
+
* @throws Error if the connection has not been established yet.
|
|
255
281
|
*/
|
|
256
|
-
|
|
282
|
+
getJetStreamClient(): JetStreamClient;
|
|
283
|
+
/** Direct access to the raw NATS connection, or `null` if not yet connected. */
|
|
284
|
+
get unwrap(): NatsConnection | null;
|
|
285
|
+
/**
|
|
286
|
+
* Gracefully shut down the connection.
|
|
287
|
+
*
|
|
288
|
+
* Sequence: drain → wait for close. Falls back to force-close on error.
|
|
289
|
+
*/
|
|
290
|
+
shutdown(): Promise<void>;
|
|
291
|
+
private initJetStreamManager;
|
|
292
|
+
/** Internal: establish the physical connection with reconnect monitoring. */
|
|
293
|
+
private establish;
|
|
294
|
+
/** Handle a single `nc.status()` event, emitting hooks and span events. */
|
|
295
|
+
private handleStatusEvent;
|
|
296
|
+
/** Subscribe to connection status events and emit hooks. */
|
|
297
|
+
private monitorStatus;
|
|
257
298
|
}
|
|
299
|
+
|
|
258
300
|
/**
|
|
259
|
-
*
|
|
301
|
+
* NestJS ClientProxy implementation for the JetStream transport.
|
|
260
302
|
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
303
|
+
* Supports two operational modes:
|
|
304
|
+
* - **Core mode** (default): Uses `nc.request()` for RPC, `nc.publish()` for events.
|
|
305
|
+
* - **JetStream mode**: Uses `js.publish()` for RPC commands + inbox for responses.
|
|
306
|
+
*
|
|
307
|
+
* Events always go through JetStream publish for guaranteed delivery.
|
|
308
|
+
* The mode only affects RPC (request/reply) behavior.
|
|
309
|
+
*
|
|
310
|
+
* Clients are lightweight — they share the NATS connection from `forRoot()`.
|
|
263
311
|
*/
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
312
|
+
declare class JetstreamClient extends ClientProxy {
|
|
313
|
+
private readonly rootOptions;
|
|
314
|
+
private readonly connection;
|
|
315
|
+
private readonly codec;
|
|
316
|
+
private readonly eventBus;
|
|
317
|
+
private readonly logger;
|
|
318
|
+
/** Target service name this client sends messages to. */
|
|
319
|
+
private readonly targetName;
|
|
320
|
+
/** Pre-cached caller name derived from rootOptions.name, computed once in constructor. */
|
|
321
|
+
private readonly callerName;
|
|
269
322
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
323
|
+
* Subject prefixes of the form `{serviceName}__microservice.{kind}.` — one
|
|
324
|
+
* per stream kind this client may publish to. Built once in the constructor
|
|
325
|
+
* so producing a full subject is a single string concat with the user pattern.
|
|
272
326
|
*/
|
|
273
|
-
|
|
327
|
+
private readonly eventSubjectPrefix;
|
|
328
|
+
private readonly commandSubjectPrefix;
|
|
329
|
+
private readonly orderedSubjectPrefix;
|
|
274
330
|
/**
|
|
275
|
-
* RPC
|
|
276
|
-
*
|
|
331
|
+
* RPC configuration snapshots. The values are derived from rootOptions at
|
|
332
|
+
* construction time so the publish hot path never has to re-run
|
|
333
|
+
* isCoreRpcMode / getRpcTimeout on every call.
|
|
277
334
|
*/
|
|
278
|
-
|
|
335
|
+
private readonly isCoreMode;
|
|
336
|
+
private readonly defaultRpcTimeout;
|
|
337
|
+
/** Resolved OpenTelemetry configuration, computed once in the constructor. */
|
|
338
|
+
private readonly otel;
|
|
339
|
+
/** Server endpoint parts used for `server.address` / `server.port` span attributes. */
|
|
340
|
+
private readonly serverEndpoint;
|
|
341
|
+
/** Shared inbox for JetStream-mode RPC responses. */
|
|
342
|
+
private inbox;
|
|
343
|
+
private inboxSubscription;
|
|
344
|
+
/** Pending JetStream-mode RPC callbacks, keyed by correlation ID. */
|
|
345
|
+
private readonly pendingMessages;
|
|
346
|
+
/** Pending JetStream-mode RPC timeouts, keyed by correlation ID. */
|
|
347
|
+
private readonly pendingTimeouts;
|
|
348
|
+
/** Subscription to connection status events for disconnect handling. */
|
|
349
|
+
private statusSubscription;
|
|
279
350
|
/**
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
351
|
+
* Cached readiness flag. Once `connect()` has wired the inbox and status
|
|
352
|
+
* subscription, subsequent publishes skip the `await connect()` microtask
|
|
353
|
+
* and reach for the underlying connection synchronously instead.
|
|
283
354
|
*/
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
events?: StreamConsumerOverrides;
|
|
287
|
-
/** Broadcast event stream/consumer overrides. */
|
|
288
|
-
broadcast?: StreamConsumerOverrides;
|
|
355
|
+
private readyForPublish;
|
|
356
|
+
constructor(rootOptions: JetstreamModuleOptions, targetServiceName: string, connection: ConnectionProvider, codec: Codec, eventBus: EventBus);
|
|
289
357
|
/**
|
|
290
|
-
*
|
|
358
|
+
* Establish connection. Called automatically by NestJS on first use.
|
|
359
|
+
*
|
|
360
|
+
* Sets up the JetStream RPC inbox (if in JetStream mode) and subscribes
|
|
361
|
+
* to connection status events for fail-fast disconnect handling.
|
|
362
|
+
*
|
|
363
|
+
* @returns The underlying NATS connection.
|
|
364
|
+
*/
|
|
365
|
+
connect(): Promise<NatsConnection>;
|
|
366
|
+
/** Clean up resources: reject pending RPCs, unsubscribe from status events. */
|
|
367
|
+
close(): Promise<void>;
|
|
368
|
+
/**
|
|
369
|
+
* Direct access to the raw NATS connection.
|
|
370
|
+
*
|
|
371
|
+
* @throws Error if not connected.
|
|
372
|
+
*/
|
|
373
|
+
unwrap<T = NatsConnection>(): T;
|
|
374
|
+
/**
|
|
375
|
+
* Publish a fire-and-forget event to JetStream.
|
|
376
|
+
*
|
|
377
|
+
* Events are published to either the workqueue stream or broadcast stream
|
|
378
|
+
* depending on the subject prefix. When a schedule is present the message
|
|
379
|
+
* is published to a `_sch` subject within the same stream, with the target
|
|
380
|
+
* set to the original event subject.
|
|
381
|
+
*/
|
|
382
|
+
protected dispatchEvent<T = unknown>(packet: ReadPacket): Promise<T>;
|
|
383
|
+
/**
|
|
384
|
+
* Publish an RPC command and register callback for response.
|
|
385
|
+
*
|
|
386
|
+
* Core mode: uses nc.request() with timeout.
|
|
387
|
+
* JetStream mode: publishes to stream + waits for inbox response.
|
|
388
|
+
*/
|
|
389
|
+
protected publish(packet: ReadPacket, callback: (p: WritePacket) => void): () => void;
|
|
390
|
+
/** Core mode: nc.request() with timeout. */
|
|
391
|
+
private publishCoreRpc;
|
|
392
|
+
/** JetStream mode: publish to stream + wait for inbox response. */
|
|
393
|
+
private publishJetStreamRpc;
|
|
394
|
+
/** Fail-fast all pending JetStream RPC callbacks on connection loss. */
|
|
395
|
+
private handleDisconnect;
|
|
396
|
+
/** Reject all pending RPC callbacks, clear timeouts, and tear down inbox. */
|
|
397
|
+
private rejectPendingRpcs;
|
|
398
|
+
/** Setup shared inbox subscription for JetStream RPC responses. */
|
|
399
|
+
private setupInbox;
|
|
400
|
+
/** Route an inbox reply to the matching pending callback. */
|
|
401
|
+
private routeInboxReply;
|
|
402
|
+
/**
|
|
403
|
+
* Resolve a user pattern to a fully-qualified NATS subject, dispatching
|
|
404
|
+
* between the event, broadcast, and ordered prefixes.
|
|
405
|
+
*
|
|
406
|
+
* The leading-char check short-circuits the `startsWith` comparisons for
|
|
407
|
+
* patterns that cannot possibly carry a broadcast/ordered marker, which is
|
|
408
|
+
* the overwhelmingly common case.
|
|
409
|
+
*/
|
|
410
|
+
private buildEventSubject;
|
|
411
|
+
/** Build NATS headers merging custom headers with transport headers. */
|
|
412
|
+
private buildHeaders;
|
|
413
|
+
/** Extract data, headers, timeout, and schedule from raw packet data or JetstreamRecord. */
|
|
414
|
+
private extractRecordData;
|
|
415
|
+
/**
|
|
416
|
+
* Build a schedule-holder subject for NATS message scheduling.
|
|
417
|
+
*
|
|
418
|
+
* The schedule-holder subject resides in the same stream as the target but
|
|
419
|
+
* uses a separate `_sch` namespace that is NOT matched by any consumer filter.
|
|
420
|
+
* NATS holds the message and publishes it to the target subject after the delay.
|
|
421
|
+
*
|
|
422
|
+
* Examples:
|
|
423
|
+
* - `{svc}__microservice.ev.order.reminder` → `{svc}__microservice._sch.order.reminder`
|
|
424
|
+
* - `broadcast.config.updated` → `broadcast._sch.config.updated`
|
|
425
|
+
*/
|
|
426
|
+
private buildScheduleSubject;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Immutable message record for JetStream transport.
|
|
431
|
+
*
|
|
432
|
+
* Compatible with NestJS record builder pattern (like RmqRecord, NatsRecord).
|
|
433
|
+
* Pass as the second argument to `client.send()` or `client.emit()`.
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* ```typescript
|
|
437
|
+
* const record = new JetstreamRecordBuilder({ id: 1 })
|
|
438
|
+
* .setHeader('x-tenant', 'acme')
|
|
439
|
+
* .setTimeout(5000)
|
|
440
|
+
* .build();
|
|
441
|
+
*
|
|
442
|
+
* client.send('get.user', record);
|
|
443
|
+
* ```
|
|
444
|
+
*/
|
|
445
|
+
declare class JetstreamRecord<TData = unknown> {
|
|
446
|
+
/** Message payload. */
|
|
447
|
+
readonly data: TData;
|
|
448
|
+
/** Custom headers set via {@link JetstreamRecordBuilder.setHeader}. */
|
|
449
|
+
readonly headers: ReadonlyMap<string, string>;
|
|
450
|
+
/** Per-request RPC timeout override in ms. */
|
|
451
|
+
readonly timeout?: number | undefined;
|
|
452
|
+
/** Custom message ID for JetStream deduplication. */
|
|
453
|
+
readonly messageId?: string | undefined;
|
|
454
|
+
/** Schedule options for delayed delivery. */
|
|
455
|
+
readonly schedule?: ScheduleRecordOptions | undefined;
|
|
456
|
+
/** Per-message TTL as Go duration string (e.g. "30s", "5m"). */
|
|
457
|
+
readonly ttl?: string | undefined;
|
|
458
|
+
constructor(
|
|
459
|
+
/** Message payload. */
|
|
460
|
+
data: TData,
|
|
461
|
+
/** Custom headers set via {@link JetstreamRecordBuilder.setHeader}. */
|
|
462
|
+
headers: ReadonlyMap<string, string>,
|
|
463
|
+
/** Per-request RPC timeout override in ms. */
|
|
464
|
+
timeout?: number | undefined,
|
|
465
|
+
/** Custom message ID for JetStream deduplication. */
|
|
466
|
+
messageId?: string | undefined,
|
|
467
|
+
/** Schedule options for delayed delivery. */
|
|
468
|
+
schedule?: ScheduleRecordOptions | undefined,
|
|
469
|
+
/** Per-message TTL as Go duration string (e.g. "30s", "5m"). */
|
|
470
|
+
ttl?: string | undefined);
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Fluent builder for constructing JetstreamRecord instances.
|
|
474
|
+
*
|
|
475
|
+
* Protected headers (`correlation-id`, `reply-to`, `error`) cannot be
|
|
476
|
+
* set by the user — attempting to do so throws an error at build time.
|
|
477
|
+
*/
|
|
478
|
+
declare class JetstreamRecordBuilder<TData = unknown> {
|
|
479
|
+
private data;
|
|
480
|
+
private readonly headers;
|
|
481
|
+
private timeout;
|
|
482
|
+
private messageId;
|
|
483
|
+
private scheduleOptions;
|
|
484
|
+
private ttlDuration;
|
|
485
|
+
constructor(data?: TData);
|
|
486
|
+
/**
|
|
487
|
+
* Set the message payload.
|
|
488
|
+
*
|
|
489
|
+
* @param data - Payload to serialize via the configured {@link Codec}.
|
|
490
|
+
*/
|
|
491
|
+
setData(data: TData): this;
|
|
492
|
+
/**
|
|
493
|
+
* Set a single custom header.
|
|
494
|
+
*
|
|
495
|
+
* @param key - Header name (e.g. `'x-tenant'`).
|
|
496
|
+
* @param value - Header value.
|
|
497
|
+
* @throws Error if the header name is reserved by the transport.
|
|
498
|
+
*/
|
|
499
|
+
setHeader(key: string, value: string): this;
|
|
500
|
+
/**
|
|
501
|
+
* Set multiple custom headers at once.
|
|
502
|
+
*
|
|
503
|
+
* @param headers - Key-value pairs to set as headers.
|
|
504
|
+
* @throws Error if any header name is reserved by the transport.
|
|
505
|
+
*/
|
|
506
|
+
setHeaders(headers: Record<string, string>): this;
|
|
507
|
+
/**
|
|
508
|
+
* Set a custom message ID for JetStream deduplication.
|
|
509
|
+
*
|
|
510
|
+
* NATS JetStream uses this ID to detect duplicate publishes within the
|
|
511
|
+
* stream's `duplicate_window`. If two messages with the same ID arrive
|
|
512
|
+
* within the window, the second is silently dropped.
|
|
513
|
+
*
|
|
514
|
+
* When not set, a random UUID is generated automatically.
|
|
515
|
+
*
|
|
516
|
+
* @param id - Unique message identifier (e.g. order ID, idempotency key).
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```typescript
|
|
520
|
+
* new JetstreamRecordBuilder(data)
|
|
521
|
+
* .setMessageId(`order-${order.id}`)
|
|
522
|
+
* .build();
|
|
523
|
+
* ```
|
|
524
|
+
*/
|
|
525
|
+
setMessageId(id: string): this;
|
|
526
|
+
/**
|
|
527
|
+
* Set per-request RPC timeout.
|
|
528
|
+
*
|
|
529
|
+
* @param ms - Timeout in milliseconds. Overrides the global RPC timeout for this request only.
|
|
530
|
+
*/
|
|
531
|
+
setTimeout(ms: number): this;
|
|
532
|
+
/**
|
|
533
|
+
* Schedule one-shot delayed delivery.
|
|
534
|
+
*
|
|
535
|
+
* The message is held by NATS and delivered to the event consumer
|
|
536
|
+
* at the specified time. Requires NATS >= 2.12 and `allow_msg_schedules: true`
|
|
537
|
+
* on the event stream (via `events: { stream: { allow_msg_schedules: true } }`).
|
|
538
|
+
*
|
|
539
|
+
* Only meaningful for events (`client.emit()`). If used with RPC
|
|
540
|
+
* (`client.send()`), a warning is logged and the schedule is ignored.
|
|
541
|
+
*
|
|
542
|
+
* @param date - Delivery time. Must be in the future.
|
|
543
|
+
* @throws Error if the date is not in the future.
|
|
544
|
+
*/
|
|
545
|
+
scheduleAt(date: Date): this;
|
|
546
|
+
/**
|
|
547
|
+
* Set per-message TTL (time-to-live).
|
|
548
|
+
*
|
|
549
|
+
* The message expires individually after the specified duration,
|
|
550
|
+
* independent of the stream's `max_age`. Requires NATS >= 2.11 and
|
|
551
|
+
* `allow_msg_ttl: true` on the stream.
|
|
552
|
+
*
|
|
553
|
+
* Only meaningful for events (`client.emit()`). If used with RPC
|
|
554
|
+
* (`client.send()`), a warning is logged and the TTL is ignored.
|
|
555
|
+
*
|
|
556
|
+
* @param nanos - TTL in nanoseconds. Use {@link toNanos} for human-readable values.
|
|
557
|
+
*
|
|
558
|
+
* @example
|
|
559
|
+
* ```typescript
|
|
560
|
+
* import { toNanos } from '@horizon-republic/nestjs-jetstream';
|
|
561
|
+
*
|
|
562
|
+
* new JetstreamRecordBuilder(payload).ttl(toNanos(30, 'minutes')).build();
|
|
563
|
+
* new JetstreamRecordBuilder(payload).ttl(toNanos(24, 'hours')).build();
|
|
564
|
+
* ```
|
|
565
|
+
*/
|
|
566
|
+
ttl(nanos: number): this;
|
|
567
|
+
/**
|
|
568
|
+
* Build the immutable {@link JetstreamRecord}.
|
|
569
|
+
*
|
|
570
|
+
* @returns A frozen record ready to pass to `client.send()` or `client.emit()`.
|
|
571
|
+
*/
|
|
572
|
+
build(): JetstreamRecord<TData>;
|
|
573
|
+
/**
|
|
574
|
+
* Validate that a header key is not reserved. NATS treats header names
|
|
575
|
+
* case-insensitively, so the check is against the lowercase form to keep
|
|
576
|
+
* `'X-Correlation-ID'`, `'x-correlation-id'`, and any other casing in
|
|
577
|
+
* lockstep. `RESERVED_HEADERS` is defined as an all-lowercase set.
|
|
578
|
+
*/
|
|
579
|
+
private validateHeaderKey;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/** Tag attached to every outgoing publish span so consumers can distinguish event / RPC / broadcast / ordered flows. */
|
|
583
|
+
declare enum PublishKind {
|
|
584
|
+
Event = "event",
|
|
585
|
+
RpcRequest = "rpc.request",
|
|
586
|
+
Broadcast = "broadcast",
|
|
587
|
+
Ordered = "ordered"
|
|
588
|
+
}
|
|
589
|
+
/** Tag attached to every incoming consume span. `Rpc` covers both Core and JetStream RPC handlers. */
|
|
590
|
+
declare enum ConsumeKind {
|
|
591
|
+
Event = "event",
|
|
592
|
+
Rpc = "rpc",
|
|
593
|
+
Broadcast = "broadcast",
|
|
594
|
+
Ordered = "ordered"
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Handler metadata for the dispatched message. `pattern` is always set;
|
|
598
|
+
* `className` / `methodName` come from NestJS reflection when available.
|
|
599
|
+
*/
|
|
600
|
+
interface HandlerMetadata {
|
|
601
|
+
readonly pattern: string;
|
|
602
|
+
readonly className?: string;
|
|
603
|
+
readonly methodName?: string;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Host / port pair surfaced as `server.address` / `server.port` span
|
|
607
|
+
* attributes. `port` is optional — OTel semconv makes it conditional on
|
|
608
|
+
* being different from the protocol default, and we'd rather emit nothing
|
|
609
|
+
* than invent a number the user never configured.
|
|
610
|
+
*/
|
|
611
|
+
interface ServerEndpoint {
|
|
612
|
+
readonly host: string;
|
|
613
|
+
readonly port?: number;
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Minimum message shape the consume span helper requires. Both `JsMsg`
|
|
617
|
+
* (JetStream) and Core NATS `Msg` satisfy it structurally; JetStream-only
|
|
618
|
+
* delivery metadata (`info`) is read separately and omitted on the Core
|
|
619
|
+
* RPC path.
|
|
620
|
+
*/
|
|
621
|
+
interface ConsumeSourceMsg {
|
|
622
|
+
readonly subject: string;
|
|
623
|
+
readonly data: Uint8Array;
|
|
624
|
+
readonly headers?: MsgHdrs;
|
|
625
|
+
}
|
|
626
|
+
/** Context passed to {@link OtelOptions.publishHook} for an outgoing publish. */
|
|
627
|
+
interface JetstreamPublishContext {
|
|
628
|
+
/** Fully-resolved subject the message is being published to. */
|
|
629
|
+
readonly subject: string;
|
|
630
|
+
/** The record being published (payload, headers, builder-supplied options). */
|
|
631
|
+
readonly record: JetstreamRecord;
|
|
632
|
+
/** Classification of the outgoing operation. */
|
|
633
|
+
readonly kind: PublishKind;
|
|
634
|
+
}
|
|
635
|
+
/** Context passed to {@link OtelOptions.consumeHook} for an incoming dispatch. */
|
|
636
|
+
interface JetstreamConsumeContext {
|
|
637
|
+
/** Fully-resolved subject of the incoming message. */
|
|
638
|
+
readonly subject: string;
|
|
639
|
+
/**
|
|
640
|
+
* The incoming NATS message. JetStream messages (events, broadcast,
|
|
641
|
+
* ordered, JetStream RPC) satisfy `JsMsg`; Core RPC messages satisfy
|
|
642
|
+
* the looser {@link ConsumeSourceMsg} shape only. Narrow on `kind` to
|
|
643
|
+
* decide which fields are safe to access.
|
|
644
|
+
*/
|
|
645
|
+
readonly msg: ConsumeSourceMsg;
|
|
646
|
+
/** Handler metadata; see {@link HandlerMetadata}. */
|
|
647
|
+
readonly handlerMetadata: HandlerMetadata;
|
|
648
|
+
/** Classification of the incoming operation. */
|
|
649
|
+
readonly kind: ConsumeKind;
|
|
650
|
+
}
|
|
651
|
+
/** Context passed to {@link OtelOptions.responseHook} once an outcome is known, just before the span ends. */
|
|
652
|
+
interface JetstreamResponseContext {
|
|
653
|
+
/** Subject the operation targeted. */
|
|
654
|
+
readonly subject: string;
|
|
655
|
+
/** Wall-clock duration of the operation in milliseconds. */
|
|
656
|
+
readonly durationMs: number;
|
|
657
|
+
/** Decoded reply payload for RPC client spans when available. */
|
|
658
|
+
readonly reply?: unknown;
|
|
659
|
+
/** Error instance if the operation failed. */
|
|
660
|
+
readonly error?: Error;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Classification outcome for a thrown error. Affects span status and
|
|
664
|
+
* attributes only — reply envelopes and internal logging are unchanged.
|
|
665
|
+
*/
|
|
666
|
+
type ErrorClassification = 'expected' | 'unexpected';
|
|
667
|
+
/** Object form of {@link OtelOptions.captureBody}. */
|
|
668
|
+
interface CaptureBodyOptions {
|
|
669
|
+
/**
|
|
670
|
+
* Maximum number of bytes to capture. Payloads longer than this are
|
|
671
|
+
* truncated; a `messaging.nats.message.body.truncated` attribute is
|
|
672
|
+
* added to indicate truncation occurred.
|
|
673
|
+
*
|
|
674
|
+
* @default 4096
|
|
675
|
+
*/
|
|
676
|
+
readonly maxBytes?: number;
|
|
677
|
+
/**
|
|
678
|
+
* Only capture body for subjects matching these glob patterns. Each
|
|
679
|
+
* pattern supports `*` wildcards and an optional leading `!` for
|
|
680
|
+
* exclusion. When omitted, body capture applies to all subjects.
|
|
681
|
+
*/
|
|
682
|
+
readonly subjectAllowlist?: readonly string[];
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* OpenTelemetry configuration for `JetstreamModule.forRoot({ otel: … })`.
|
|
686
|
+
* All fields are optional; when the host app has not registered an OTel
|
|
687
|
+
* SDK, every call made by the library is a no-op regardless of config.
|
|
688
|
+
*/
|
|
689
|
+
interface OtelOptions {
|
|
690
|
+
/**
|
|
691
|
+
* Global kill switch. When `false`, no spans are emitted, no propagation
|
|
692
|
+
* is attempted, and no hooks fire.
|
|
693
|
+
*
|
|
694
|
+
* @default true
|
|
695
|
+
*/
|
|
696
|
+
readonly enabled?: boolean;
|
|
697
|
+
/**
|
|
698
|
+
* Which trace kinds to emit.
|
|
699
|
+
*
|
|
700
|
+
* - `'default'` — publish, consume, RPC client round-trip, dead letter
|
|
701
|
+
* - `'all'` — every trace kind defined in {@link JetstreamTrace}
|
|
702
|
+
* - `'none'` — emit no spans at all (useful with `enabled: true` for
|
|
703
|
+
* pure trace-context propagation without the span overhead)
|
|
704
|
+
* - `JetstreamTrace[]` — explicit selection
|
|
705
|
+
*
|
|
706
|
+
* @default 'default'
|
|
707
|
+
*/
|
|
708
|
+
readonly traces?: readonly JetstreamTrace[] | 'default' | 'all' | 'none';
|
|
709
|
+
/**
|
|
710
|
+
* Header names to capture as span attributes (`messaging.header.<name>`).
|
|
711
|
+
* Match is case-insensitive. Glob wildcards (`*`) and negation (`!prefix-*`)
|
|
712
|
+
* are supported in the per-pattern form.
|
|
713
|
+
*
|
|
714
|
+
* SECURITY / GDPR: headers may contain authentication tokens, session
|
|
715
|
+
* identifiers, or other sensitive data. Captured values are exported to
|
|
716
|
+
* the configured OTel backend. Use an explicit allowlist in production.
|
|
717
|
+
* Setting this to `true` captures every header and is intended for
|
|
718
|
+
* development environments only.
|
|
719
|
+
*
|
|
720
|
+
* Transport-internal headers (`x-correlation-id`, `x-reply-to`, `x-error`,
|
|
721
|
+
* `x-subject`, `x-caller-name`) and propagator-owned headers
|
|
722
|
+
* (`traceparent`, `tracestate`, `baggage`, `sentry-trace`, `b3`, …) are
|
|
723
|
+
* always suppressed regardless of the allowlist.
|
|
724
|
+
*
|
|
725
|
+
* @default ['x-request-id']
|
|
726
|
+
*/
|
|
727
|
+
readonly captureHeaders?: readonly string[] | boolean;
|
|
728
|
+
/**
|
|
729
|
+
* Capture the message payload as the `messaging.nats.message.body` span
|
|
730
|
+
* attribute. Defaults to `false` for privacy and cost reasons.
|
|
731
|
+
*
|
|
732
|
+
* Passing `true` captures up to 4 KiB per message. Use the object form
|
|
733
|
+
* for finer control over size and subject scope.
|
|
734
|
+
*
|
|
735
|
+
* SECURITY / GDPR: payloads commonly contain PII, credentials, financial
|
|
736
|
+
* data, or content regulated by HIPAA / PCI-DSS. Enabling body capture
|
|
737
|
+
* in production is almost always a policy violation. Prefer enabling
|
|
738
|
+
* only in development, or pair with a custom `SpanProcessor` that
|
|
739
|
+
* scrubs or drops the attribute before export.
|
|
740
|
+
*
|
|
741
|
+
* @default false
|
|
742
|
+
*/
|
|
743
|
+
readonly captureBody?: boolean | CaptureBodyOptions;
|
|
744
|
+
/**
|
|
745
|
+
* Invoked after a publish span has been started and before the actual
|
|
746
|
+
* publish call executes. Use to enrich the span with custom attributes.
|
|
747
|
+
* Must be synchronous — thrown errors are caught and logged at debug
|
|
748
|
+
* level without affecting the publish path.
|
|
749
|
+
*/
|
|
750
|
+
publishHook?(span: Span, ctx: JetstreamPublishContext): void;
|
|
751
|
+
/**
|
|
752
|
+
* Invoked after a consume span has been started and before the handler
|
|
753
|
+
* is dispatched. Use to enrich the span with custom attributes derived
|
|
754
|
+
* from the incoming message or handler metadata.
|
|
755
|
+
*/
|
|
756
|
+
consumeHook?(span: Span, ctx: JetstreamConsumeContext): void;
|
|
757
|
+
/**
|
|
758
|
+
* Invoked once an operation's outcome is known (success, error, or
|
|
759
|
+
* timeout) and the span status has been set, just before the span ends.
|
|
760
|
+
* Fires for publish, consume, and RPC client spans.
|
|
761
|
+
*/
|
|
762
|
+
responseHook?(span: Span, ctx: JetstreamResponseContext): void;
|
|
763
|
+
/**
|
|
764
|
+
* Predicate evaluated at the top of every outgoing publish. Returning
|
|
765
|
+
* `false` skips span creation for that publish; propagation of trace
|
|
766
|
+
* context through headers still occurs, so downstream consumers are
|
|
767
|
+
* unaffected. Useful for suppressing noise from health-check or
|
|
768
|
+
* internal-only subjects.
|
|
769
|
+
*/
|
|
770
|
+
shouldTracePublish?(subject: string, record: JetstreamRecord): boolean;
|
|
771
|
+
/**
|
|
772
|
+
* Predicate evaluated at the top of every incoming message delivery.
|
|
773
|
+
* Returning `false` skips span creation for that delivery; the handler
|
|
774
|
+
* still executes normally and trace context is still extracted from
|
|
775
|
+
* headers for downstream calls.
|
|
776
|
+
*/
|
|
777
|
+
shouldTraceConsume?(subject: string, msg: ConsumeSourceMsg): boolean;
|
|
778
|
+
/**
|
|
779
|
+
* Classify a thrown error as `'expected'` (business error, part of the
|
|
780
|
+
* RPC contract) or `'unexpected'` (infrastructure failure or bug). Drives
|
|
781
|
+
* OpenTelemetry span status and attributes only.
|
|
782
|
+
*
|
|
783
|
+
* - `'expected'` → span status `OK` with `jetstream.rpc.reply.has_error`
|
|
784
|
+
* and `jetstream.rpc.reply.error.code` attributes
|
|
785
|
+
* - `'unexpected'` → span status `ERROR` with `span.recordException(err)`
|
|
786
|
+
*
|
|
787
|
+
* Reply envelopes delivered to RPC clients are identical in both cases.
|
|
788
|
+
* This classification affects only the observability artifact.
|
|
789
|
+
*
|
|
790
|
+
* The default recognizes NestJS-idiomatic primitives for business errors:
|
|
791
|
+
* `RpcException` and `HttpException`. Teams with custom error hierarchies
|
|
792
|
+
* override to recognize their own types.
|
|
793
|
+
*
|
|
794
|
+
* @example
|
|
795
|
+
* errorClassifier: (err) => {
|
|
796
|
+
* if (err instanceof MyDomainError) return 'expected';
|
|
797
|
+
* if (err?.code?.startsWith('BIZ_')) return 'expected';
|
|
798
|
+
* return 'unexpected';
|
|
799
|
+
* }
|
|
800
|
+
*/
|
|
801
|
+
errorClassifier?(err: unknown): ErrorClassification;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Stream config overrides exposed to users.
|
|
806
|
+
*
|
|
807
|
+
* `retention` is excluded because it is controlled by the transport layer
|
|
808
|
+
* (Workqueue for events/commands, Limits for broadcast/ordered).
|
|
809
|
+
* Any `retention` value provided at runtime is silently stripped.
|
|
810
|
+
*/
|
|
811
|
+
type StreamConfigOverrides = Partial<Omit<StreamConfig, 'retention'>>;
|
|
812
|
+
/**
|
|
813
|
+
* RPC transport configuration.
|
|
814
|
+
*
|
|
815
|
+
* Discriminated union on `mode`:
|
|
816
|
+
* - `'core'` — NATS native request/reply. Lowest latency.
|
|
817
|
+
* - `'jetstream'` — Commands persisted in JetStream. Responses via Core NATS inbox.
|
|
818
|
+
*
|
|
819
|
+
* When `mode` is `'core'`, only `timeout` is available.
|
|
820
|
+
* When `mode` is `'jetstream'`, additional stream/consumer overrides are exposed.
|
|
821
|
+
*/
|
|
822
|
+
type RpcConfig = {
|
|
823
|
+
mode: 'core';
|
|
824
|
+
/** Request timeout in ms. Default: 30_000. */
|
|
825
|
+
timeout?: number;
|
|
826
|
+
} | {
|
|
827
|
+
mode: 'jetstream';
|
|
828
|
+
/** Handler timeout in ms. Default: 180_000 (3 min). */
|
|
829
|
+
timeout?: number;
|
|
830
|
+
/** Raw NATS StreamConfig overrides for the command stream. */
|
|
831
|
+
stream?: StreamConfigOverrides;
|
|
832
|
+
/** Raw NATS ConsumerConfig overrides for the command consumer. */
|
|
833
|
+
consumer?: Partial<ConsumerConfig>;
|
|
834
|
+
/** Options passed to the nats.js `consumer.consume()` call for the command consumer. */
|
|
835
|
+
consume?: Partial<ConsumeOptions>;
|
|
836
|
+
/** Maximum number of concurrent RPC handler executions. */
|
|
837
|
+
concurrency?: number;
|
|
838
|
+
/**
|
|
839
|
+
* Auto-extend ack deadline via `msg.working()` during RPC handler execution.
|
|
840
|
+
* The RPC handler timeout (`setTimeout` + `msg.term()`) still acts as the hard cap.
|
|
841
|
+
*/
|
|
842
|
+
ackExtension?: boolean | number;
|
|
843
|
+
};
|
|
844
|
+
/** Overrides for JetStream stream and consumer configuration. */
|
|
845
|
+
interface StreamConsumerOverrides {
|
|
846
|
+
stream?: StreamConfigOverrides;
|
|
847
|
+
consumer?: Partial<ConsumerConfig>;
|
|
848
|
+
/**
|
|
849
|
+
* Options passed to the nats.js `consumer.consume()` call.
|
|
850
|
+
* Controls prefetch buffer size, idle heartbeat interval, and auto-refill thresholds.
|
|
851
|
+
*
|
|
852
|
+
* nats.js supports two consumption modes (message-based and byte-based).
|
|
853
|
+
* Do not mix `max_bytes`/`threshold_bytes` with `threshold_messages` —
|
|
854
|
+
* use one mode or the other.
|
|
855
|
+
*
|
|
856
|
+
* @see https://github.com/nats-io/nats.js — ConsumeOptions
|
|
857
|
+
*/
|
|
858
|
+
consume?: Partial<ConsumeOptions>;
|
|
859
|
+
/**
|
|
860
|
+
* Maximum number of concurrent handler executions (RxJS `mergeMap` limit).
|
|
861
|
+
*
|
|
862
|
+
* Default: `undefined` (unlimited — naturally bounded by `max_ack_pending`).
|
|
863
|
+
* Set this to protect downstream systems from overload.
|
|
864
|
+
*
|
|
865
|
+
* **Important:** if `concurrency < max_ack_pending`, messages buffer in RxJS
|
|
866
|
+
* while their NATS ack timer ticks. Increase `ack_wait` proportionally to
|
|
867
|
+
* prevent unnecessary redeliveries.
|
|
868
|
+
*/
|
|
869
|
+
concurrency?: number;
|
|
870
|
+
/**
|
|
871
|
+
* Auto-extend the NATS ack deadline via `msg.working()` during handler execution.
|
|
872
|
+
*
|
|
873
|
+
* - `false` (default): disabled — NATS redelivers after `ack_wait` if not acked.
|
|
874
|
+
* - `true`: auto-extend at `ack_wait / 2` interval (calculated from consumer config).
|
|
875
|
+
* - `number`: explicit extension interval in milliseconds.
|
|
876
|
+
*/
|
|
877
|
+
ackExtension?: boolean | number;
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Configuration for ordered event consumers.
|
|
881
|
+
*
|
|
882
|
+
* Ordered consumers use Limits retention and deliver messages in strict
|
|
883
|
+
* sequential order with at-most-once delivery. No ack/nak/DLQ.
|
|
884
|
+
*
|
|
885
|
+
* Only a subset of consumer options applies — ordered consumers are
|
|
886
|
+
* ephemeral and auto-managed by nats.js.
|
|
887
|
+
*/
|
|
888
|
+
interface OrderedEventOverrides {
|
|
889
|
+
/** Stream overrides (e.g. `max_age`, `max_bytes`). */
|
|
890
|
+
stream?: StreamConfigOverrides;
|
|
891
|
+
/**
|
|
892
|
+
* Where to start reading when the consumer is (re)created.
|
|
893
|
+
* @default DeliverPolicy.All
|
|
894
|
+
*/
|
|
895
|
+
deliverPolicy?: DeliverPolicy;
|
|
896
|
+
/**
|
|
897
|
+
* Start sequence number. Only used when `deliverPolicy` is `StartSequence`.
|
|
898
|
+
*/
|
|
899
|
+
optStartSeq?: number;
|
|
900
|
+
/**
|
|
901
|
+
* Start time (ISO string). Only used when `deliverPolicy` is `StartTime`.
|
|
902
|
+
*/
|
|
903
|
+
optStartTime?: string;
|
|
904
|
+
/**
|
|
905
|
+
* Replay policy for historical messages.
|
|
906
|
+
* @default ReplayPolicy.Instant
|
|
907
|
+
*/
|
|
908
|
+
replayPolicy?: ReplayPolicy;
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Configuration for the handler metadata KV registry.
|
|
912
|
+
*
|
|
913
|
+
* When any handler has `meta` in its extras, the transport writes metadata
|
|
914
|
+
* entries to a NATS KV bucket at startup. External services (API gateways,
|
|
915
|
+
* dashboards) can watch the bucket for service discovery.
|
|
916
|
+
*
|
|
917
|
+
* All fields are optional — sensible defaults are applied.
|
|
918
|
+
*/
|
|
919
|
+
interface MetadataRegistryOptions {
|
|
920
|
+
/**
|
|
921
|
+
* KV bucket name.
|
|
922
|
+
* @default 'handler_registry'
|
|
923
|
+
*/
|
|
924
|
+
bucket?: string;
|
|
925
|
+
/**
|
|
926
|
+
* Number of KV bucket replicas. Must be an odd number (1, 3, 5, 7, ...).
|
|
927
|
+
* Requires a NATS cluster with at least this many nodes.
|
|
928
|
+
* @default 1
|
|
929
|
+
*/
|
|
930
|
+
replicas?: number;
|
|
931
|
+
/**
|
|
932
|
+
* KV bucket TTL in milliseconds.
|
|
933
|
+
*
|
|
934
|
+
* Entries expire automatically unless refreshed by a heartbeat.
|
|
935
|
+
* The transport refreshes entries every `ttl / 2` while the pod is alive.
|
|
936
|
+
* When the pod stops (graceful or crash), entries expire after this duration.
|
|
937
|
+
*
|
|
938
|
+
* @default 30_000 (30 seconds)
|
|
939
|
+
*/
|
|
940
|
+
ttl?: number;
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Root module configuration for `JetstreamModule.forRoot()`.
|
|
944
|
+
*
|
|
945
|
+
* Minimal usage requires only `name` and `servers`.
|
|
946
|
+
* All other fields have production-ready defaults.
|
|
947
|
+
*/
|
|
948
|
+
interface JetstreamModuleOptions {
|
|
949
|
+
/** Service name. Used for stream/consumer/subject naming. */
|
|
950
|
+
name: string;
|
|
951
|
+
/** NATS server URLs. */
|
|
952
|
+
servers: string[];
|
|
953
|
+
/**
|
|
954
|
+
* Global message codec.
|
|
955
|
+
* @default JsonCodec
|
|
956
|
+
*/
|
|
957
|
+
codec?: Codec;
|
|
958
|
+
/**
|
|
959
|
+
* RPC transport mode and configuration.
|
|
960
|
+
* @default { mode: 'core' }
|
|
961
|
+
*/
|
|
962
|
+
rpc?: RpcConfig;
|
|
963
|
+
/**
|
|
964
|
+
* Enable consumer infrastructure (streams, consumers, message routing).
|
|
965
|
+
* Set to `false` for publisher-only services (e.g., API gateways).
|
|
966
|
+
* @default true
|
|
967
|
+
*/
|
|
968
|
+
consumer?: boolean;
|
|
969
|
+
/** Workqueue event stream/consumer overrides. */
|
|
970
|
+
events?: StreamConsumerOverrides;
|
|
971
|
+
/** Broadcast event stream/consumer overrides. */
|
|
972
|
+
broadcast?: StreamConsumerOverrides;
|
|
973
|
+
/**
|
|
974
|
+
* Ordered event consumer configuration.
|
|
291
975
|
*
|
|
292
976
|
* Ordered events use a separate stream with Limits retention and deliver
|
|
293
977
|
* messages in strict sequential order. Use `ordered:` prefix when publishing.
|
|
@@ -385,6 +1069,16 @@ interface JetstreamModuleOptions {
|
|
|
385
1069
|
* Merged with `name` and `servers` — those take precedence.
|
|
386
1070
|
*/
|
|
387
1071
|
connectionOptions?: Partial<ConnectionOptions>;
|
|
1072
|
+
/**
|
|
1073
|
+
* OpenTelemetry integration. When omitted, sensible defaults are applied:
|
|
1074
|
+
* tracing is enabled, default trace kinds are emitted, only standard
|
|
1075
|
+
* correlation headers are captured. If no OTel SDK is registered in the
|
|
1076
|
+
* consuming application, all tracer calls are no-ops — there is no
|
|
1077
|
+
* runtime cost.
|
|
1078
|
+
*
|
|
1079
|
+
* @see OtelOptions
|
|
1080
|
+
*/
|
|
1081
|
+
otel?: OtelOptions;
|
|
388
1082
|
}
|
|
389
1083
|
/** Options for `JetstreamModule.forFeature()`. */
|
|
390
1084
|
interface JetstreamFeatureOptions {
|
|
@@ -462,138 +1156,32 @@ interface PatternsByKind {
|
|
|
462
1156
|
/** Ordered event patterns (strict sequential delivery). */
|
|
463
1157
|
ordered: string[];
|
|
464
1158
|
}
|
|
465
|
-
/** Options for configuring event/broadcast processing behavior. */
|
|
466
|
-
interface EventProcessingConfig {
|
|
467
|
-
events?: {
|
|
468
|
-
concurrency?: number;
|
|
469
|
-
ackExtension?: boolean | number;
|
|
470
|
-
};
|
|
471
|
-
broadcast?: {
|
|
472
|
-
concurrency?: number;
|
|
473
|
-
ackExtension?: boolean | number;
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
/** Options for dead letter queue handling. */
|
|
477
|
-
interface DeadLetterConfig {
|
|
478
|
-
/**
|
|
479
|
-
* Map of stream name -> max_deliver value.
|
|
480
|
-
* Used to detect when a message from a given stream has exhausted all delivery attempts.
|
|
481
|
-
*/
|
|
482
|
-
maxDeliverByStream: Map<string, number>;
|
|
483
|
-
/** Async callback invoked when a message exhausts all deliveries. */
|
|
484
|
-
onDeadLetter(info: DeadLetterInfo): Promise<void>;
|
|
485
|
-
}
|
|
486
|
-
/** Options for configuring RPC processing behavior. */
|
|
487
|
-
interface RpcRouterOptions {
|
|
488
|
-
timeout?: number;
|
|
489
|
-
concurrency?: number;
|
|
490
|
-
ackExtension?: boolean | number;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* Central event bus for transport lifecycle notifications.
|
|
495
|
-
*
|
|
496
|
-
* Dispatches events to user-provided hooks. Events without a
|
|
497
|
-
* registered hook are silently ignored — no default logging.
|
|
498
|
-
*
|
|
499
|
-
* @example
|
|
500
|
-
* ```typescript
|
|
501
|
-
* const bus = new EventBus(logger, {
|
|
502
|
-
* [TransportEvent.Error]: (err) => sentry.captureException(err),
|
|
503
|
-
* });
|
|
504
|
-
*
|
|
505
|
-
* bus.emit(TransportEvent.Error, new Error('timeout'), 'rpc-router');
|
|
506
|
-
* // → calls sentry
|
|
507
|
-
*
|
|
508
|
-
* bus.emit(TransportEvent.Connect, 'nats://localhost:4222');
|
|
509
|
-
* // → no-op (no hook registered)
|
|
510
|
-
* ```
|
|
511
|
-
*/
|
|
512
|
-
declare class EventBus {
|
|
513
|
-
private readonly hooks;
|
|
514
|
-
private readonly logger;
|
|
515
|
-
constructor(logger: Logger, hooks?: Partial<TransportHooks>);
|
|
516
|
-
/**
|
|
517
|
-
* Emit a lifecycle event. Dispatches to custom hook if registered, otherwise no-op.
|
|
518
|
-
*
|
|
519
|
-
* @param event - The {@link TransportEvent} to emit.
|
|
520
|
-
* @param args - Arguments matching the hook signature for this event.
|
|
521
|
-
*/
|
|
522
|
-
emit<K extends keyof TransportHooks>(event: K, ...args: Parameters<TransportHooks[K]>): void;
|
|
523
|
-
/**
|
|
524
|
-
* Hot-path optimized emit for MessageRouted events.
|
|
525
|
-
* Avoids rest/spread overhead of the generic `emit()`.
|
|
526
|
-
*/
|
|
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;
|
|
535
|
-
private callHook;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* Manages the lifecycle of a single NATS connection shared across the application.
|
|
540
|
-
*
|
|
541
|
-
* Provides both Promise-based and Observable-based access to the connection:
|
|
542
|
-
* - `connect()` / `getConnection()` — async/await for one-time setup
|
|
543
|
-
* - `nc$` — cached observable (shareReplay) for reactive consumers
|
|
544
|
-
* - `status$` — live connection status event stream
|
|
545
|
-
*
|
|
546
|
-
* One instance per application, created by `JetstreamModule.forRoot()`.
|
|
547
|
-
*/
|
|
548
|
-
declare class ConnectionProvider {
|
|
549
|
-
private readonly options;
|
|
550
|
-
private readonly eventBus;
|
|
551
|
-
/** Cached observable that replays the established connection to new subscribers. */
|
|
552
|
-
readonly nc$: Observable<NatsConnection>;
|
|
553
|
-
/** Live stream of connection status events (no replay). */
|
|
554
|
-
readonly status$: Observable<Status>;
|
|
555
|
-
private readonly logger;
|
|
556
|
-
private connection;
|
|
557
|
-
private connectionPromise;
|
|
558
|
-
private jsClient;
|
|
559
|
-
private jsmInstance;
|
|
560
|
-
private jsmPromise;
|
|
561
|
-
constructor(options: JetstreamModuleOptions, eventBus: EventBus);
|
|
562
|
-
/**
|
|
563
|
-
* Establish NATS connection. Idempotent — returns cached connection on subsequent calls.
|
|
564
|
-
*
|
|
565
|
-
* @throws Error if connection is refused (fail fast).
|
|
566
|
-
*/
|
|
567
|
-
getConnection(): Promise<NatsConnection>;
|
|
568
|
-
/**
|
|
569
|
-
* Get the JetStream manager. Cached after first call.
|
|
570
|
-
*
|
|
571
|
-
* @returns The JetStreamManager for stream/consumer administration.
|
|
572
|
-
*/
|
|
573
|
-
getJetStreamManager(): Promise<JetStreamManager>;
|
|
574
|
-
/**
|
|
575
|
-
* Get a cached JetStream client.
|
|
576
|
-
*
|
|
577
|
-
* Invalidated automatically on reconnect and shutdown so consumers always
|
|
578
|
-
* operate against the live connection.
|
|
579
|
-
*
|
|
580
|
-
* @returns The cached JetStreamClient.
|
|
581
|
-
* @throws Error if the connection has not been established yet.
|
|
582
|
-
*/
|
|
583
|
-
getJetStreamClient(): JetStreamClient;
|
|
584
|
-
/** Direct access to the raw NATS connection, or `null` if not yet connected. */
|
|
585
|
-
get unwrap(): NatsConnection | null;
|
|
1159
|
+
/** Options for configuring event/broadcast processing behavior. */
|
|
1160
|
+
interface EventProcessingConfig {
|
|
1161
|
+
events?: {
|
|
1162
|
+
concurrency?: number;
|
|
1163
|
+
ackExtension?: boolean | number;
|
|
1164
|
+
};
|
|
1165
|
+
broadcast?: {
|
|
1166
|
+
concurrency?: number;
|
|
1167
|
+
ackExtension?: boolean | number;
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
/** Options for dead letter queue handling. */
|
|
1171
|
+
interface DeadLetterConfig {
|
|
586
1172
|
/**
|
|
587
|
-
*
|
|
588
|
-
*
|
|
589
|
-
* Sequence: drain → wait for close. Falls back to force-close on error.
|
|
1173
|
+
* Map of stream name -> max_deliver value.
|
|
1174
|
+
* Used to detect when a message from a given stream has exhausted all delivery attempts.
|
|
590
1175
|
*/
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
1176
|
+
maxDeliverByStream: Map<string, number>;
|
|
1177
|
+
/** Async callback invoked when a message exhausts all deliveries. */
|
|
1178
|
+
onDeadLetter(info: DeadLetterInfo): Promise<void>;
|
|
1179
|
+
}
|
|
1180
|
+
/** Options for configuring RPC processing behavior. */
|
|
1181
|
+
interface RpcRouterOptions {
|
|
1182
|
+
timeout?: number;
|
|
1183
|
+
concurrency?: number;
|
|
1184
|
+
ackExtension?: boolean | number;
|
|
597
1185
|
}
|
|
598
1186
|
|
|
599
1187
|
/**
|
|
@@ -658,13 +1246,15 @@ declare class PatternRegistry {
|
|
|
658
1246
|
* This is the default RPC mode — lowest latency, no persistence overhead.
|
|
659
1247
|
*/
|
|
660
1248
|
declare class CoreRpcServer {
|
|
661
|
-
private readonly options;
|
|
662
1249
|
private readonly connection;
|
|
663
1250
|
private readonly patternRegistry;
|
|
664
1251
|
private readonly codec;
|
|
665
1252
|
private readonly eventBus;
|
|
666
1253
|
private readonly logger;
|
|
667
1254
|
private subscription;
|
|
1255
|
+
private readonly otel;
|
|
1256
|
+
private readonly serviceName;
|
|
1257
|
+
private readonly serverEndpoint;
|
|
668
1258
|
constructor(options: JetstreamModuleOptions, connection: ConnectionProvider, patternRegistry: PatternRegistry, codec: Codec, eventBus: EventBus);
|
|
669
1259
|
/** Start listening for RPC requests on the command subject. */
|
|
670
1260
|
start(): Promise<void>;
|
|
@@ -691,6 +1281,9 @@ declare class StreamProvider {
|
|
|
691
1281
|
private readonly connection;
|
|
692
1282
|
private readonly logger;
|
|
693
1283
|
private readonly migration;
|
|
1284
|
+
private readonly otel;
|
|
1285
|
+
private readonly otelServiceName;
|
|
1286
|
+
private readonly otelEndpoint;
|
|
694
1287
|
constructor(options: JetstreamModuleOptions, connection: ConnectionProvider);
|
|
695
1288
|
/**
|
|
696
1289
|
* Ensure all required streams exist with correct configuration.
|
|
@@ -734,21 +1327,6 @@ declare class StreamProvider {
|
|
|
734
1327
|
private stripTransportControlled;
|
|
735
1328
|
}
|
|
736
1329
|
|
|
737
|
-
/**
|
|
738
|
-
* Routes incoming event messages (workqueue, broadcast, and ordered) to NestJS handlers.
|
|
739
|
-
*
|
|
740
|
-
* **Workqueue & Broadcast** — at-least-once delivery:
|
|
741
|
-
* - Success -> ack | Error -> nak (retry) | Dead letter -> term
|
|
742
|
-
*
|
|
743
|
-
* **Ordered** — strict sequential delivery:
|
|
744
|
-
* - No ack/nak/DLQ — nats.js auto-acknowledges ordered consumer messages.
|
|
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.
|
|
751
|
-
*/
|
|
752
1330
|
declare class EventRouter {
|
|
753
1331
|
private readonly messageProvider;
|
|
754
1332
|
private readonly patternRegistry;
|
|
@@ -761,6 +1339,9 @@ declare class EventRouter {
|
|
|
761
1339
|
private readonly options?;
|
|
762
1340
|
private readonly logger;
|
|
763
1341
|
private readonly subscriptions;
|
|
1342
|
+
private readonly otel;
|
|
1343
|
+
private readonly serviceName;
|
|
1344
|
+
private readonly serverEndpoint;
|
|
764
1345
|
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);
|
|
765
1346
|
/**
|
|
766
1347
|
* Update the max_deliver thresholds from actual NATS consumer configs.
|
|
@@ -775,14 +1356,11 @@ declare class EventRouter {
|
|
|
775
1356
|
private subscribeToStream;
|
|
776
1357
|
private getConcurrency;
|
|
777
1358
|
private getAckExtensionConfig;
|
|
778
|
-
/** Handle a dead letter: invoke callback, then term or nak based on result. */
|
|
779
1359
|
/**
|
|
780
|
-
*
|
|
781
|
-
*
|
|
782
|
-
*
|
|
783
|
-
*
|
|
784
|
-
* On success, terminates the message. On error, leaves it unacknowledged (nak)
|
|
785
|
-
* so NATS can retry the delivery on the next cycle.
|
|
1360
|
+
* Last-resort path for a dead letter: invoke `onDeadLetter`, then `term` on
|
|
1361
|
+
* success or `nak` on hook failure so NATS retries on the next delivery
|
|
1362
|
+
* cycle. Used when DLQ stream isn't configured, or when publishing to it
|
|
1363
|
+
* failed and we still have to surface the message somewhere observable.
|
|
786
1364
|
*/
|
|
787
1365
|
private fallbackToOnDeadLetterCallback;
|
|
788
1366
|
/**
|
|
@@ -829,7 +1407,10 @@ declare class RpcRouter {
|
|
|
829
1407
|
private resolvedAckExtensionInterval;
|
|
830
1408
|
private subscription;
|
|
831
1409
|
private cachedNc;
|
|
832
|
-
|
|
1410
|
+
private readonly otel;
|
|
1411
|
+
private readonly serviceName;
|
|
1412
|
+
private readonly serverEndpoint;
|
|
1413
|
+
constructor(messageProvider: MessageProvider, patternRegistry: PatternRegistry, connection: ConnectionProvider, codec: Codec, eventBus: EventBus, rpcOptions?: RpcRouterOptions | undefined, ackWaitMap?: Map<StreamKind, number> | undefined, options?: JetstreamModuleOptions);
|
|
833
1414
|
/** Lazily resolve the ack extension interval (needs ackWaitMap populated at runtime). */
|
|
834
1415
|
private get ackExtensionInterval();
|
|
835
1416
|
/** Start routing command messages to handlers. */
|
|
@@ -850,6 +1431,9 @@ declare class ConsumerProvider {
|
|
|
850
1431
|
private readonly streamProvider;
|
|
851
1432
|
private readonly patternRegistry;
|
|
852
1433
|
private readonly logger;
|
|
1434
|
+
private readonly otel;
|
|
1435
|
+
private readonly otelServiceName;
|
|
1436
|
+
private readonly otelEndpoint;
|
|
853
1437
|
constructor(options: JetstreamModuleOptions, connection: ConnectionProvider, streamProvider: StreamProvider, patternRegistry: PatternRegistry);
|
|
854
1438
|
/**
|
|
855
1439
|
* Ensure consumers exist for the specified kinds.
|
|
@@ -1079,411 +1663,138 @@ declare class JetstreamStrategy extends Server implements CustomTransportStrateg
|
|
|
1079
1663
|
/**
|
|
1080
1664
|
* Register event listener (required by Server base class).
|
|
1081
1665
|
*
|
|
1082
|
-
* Stores callbacks for client use. Primary lifecycle events
|
|
1083
|
-
* are routed through EventBus.
|
|
1084
|
-
*/
|
|
1085
|
-
on(event: string, callback: Function): void;
|
|
1086
|
-
/**
|
|
1087
|
-
* Unwrap the underlying NATS connection.
|
|
1088
|
-
*
|
|
1089
|
-
* @throws Error if the transport has not started.
|
|
1090
|
-
*/
|
|
1091
|
-
unwrap<T>(): T;
|
|
1092
|
-
/** Access the pattern registry (for module-level introspection). */
|
|
1093
|
-
getPatternRegistry(): PatternRegistry;
|
|
1094
|
-
/** Determine which streams and durable consumers are needed. */
|
|
1095
|
-
private resolveRequiredKinds;
|
|
1096
|
-
/** Populate the shared ack_wait map from actual NATS consumer configs. */
|
|
1097
|
-
private populateAckWaitMap;
|
|
1098
|
-
/** Build max_deliver map from actual NATS consumer configs (not options). */
|
|
1099
|
-
private buildMaxDeliverMap;
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
/** Minimal interface for anything that can be stopped during shutdown. */
|
|
1103
|
-
interface Stoppable {
|
|
1104
|
-
close(): void;
|
|
1105
|
-
}
|
|
1106
|
-
/**
|
|
1107
|
-
* Orchestrates graceful transport shutdown.
|
|
1108
|
-
*
|
|
1109
|
-
* Shutdown sequence:
|
|
1110
|
-
* 1. Emit onShutdownStart hook
|
|
1111
|
-
* 2. Stop accepting new messages (close subscriptions, stop consumers)
|
|
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.
|
|
1119
|
-
*/
|
|
1120
|
-
declare class ShutdownManager {
|
|
1121
|
-
private readonly connection;
|
|
1122
|
-
private readonly eventBus;
|
|
1123
|
-
private readonly timeout;
|
|
1124
|
-
private readonly logger;
|
|
1125
|
-
private shutdownPromise?;
|
|
1126
|
-
constructor(connection: ConnectionProvider, eventBus: EventBus, timeout: number);
|
|
1127
|
-
/**
|
|
1128
|
-
* Execute the full shutdown sequence.
|
|
1129
|
-
*
|
|
1130
|
-
* Idempotent — concurrent or repeated calls return the same promise.
|
|
1131
|
-
*
|
|
1132
|
-
* @param strategy Optional stoppable to close (stops consumers and subscriptions).
|
|
1133
|
-
*/
|
|
1134
|
-
shutdown(strategy?: Stoppable): Promise<void>;
|
|
1135
|
-
private doShutdown;
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
/**
|
|
1139
|
-
* Root module for the NestJS JetStream transport.
|
|
1140
|
-
*
|
|
1141
|
-
* - `forRoot()` / `forRootAsync()` — registers once in AppModule.
|
|
1142
|
-
* Creates shared NATS connection, codec, event bus, and optionally
|
|
1143
|
-
* the consumer infrastructure.
|
|
1144
|
-
*
|
|
1145
|
-
* - `forFeature()` — registers in feature modules.
|
|
1146
|
-
* Creates a lightweight client proxy targeting a specific service.
|
|
1147
|
-
*
|
|
1148
|
-
* @example
|
|
1149
|
-
* ```typescript
|
|
1150
|
-
* // AppModule — global setup
|
|
1151
|
-
* @Module({
|
|
1152
|
-
* imports: [
|
|
1153
|
-
* JetstreamModule.forRoot({
|
|
1154
|
-
* name: 'orders',
|
|
1155
|
-
* servers: ['nats://localhost:4222'],
|
|
1156
|
-
* }),
|
|
1157
|
-
* ],
|
|
1158
|
-
* })
|
|
1159
|
-
* export class AppModule {}
|
|
1160
|
-
*
|
|
1161
|
-
* // Feature module — per-service clients
|
|
1162
|
-
* @Module({
|
|
1163
|
-
* imports: [
|
|
1164
|
-
* JetstreamModule.forFeature({ name: 'users' }),
|
|
1165
|
-
* JetstreamModule.forFeature({ name: 'payments' }),
|
|
1166
|
-
* ],
|
|
1167
|
-
* })
|
|
1168
|
-
* export class OrdersModule {}
|
|
1169
|
-
* ```
|
|
1170
|
-
*/
|
|
1171
|
-
declare class JetstreamModule implements OnApplicationShutdown {
|
|
1172
|
-
private readonly shutdownManager?;
|
|
1173
|
-
private readonly strategy?;
|
|
1174
|
-
constructor(shutdownManager?: ShutdownManager | undefined, strategy?: (JetstreamStrategy | null) | undefined);
|
|
1175
|
-
/**
|
|
1176
|
-
* Register the JetStream transport globally.
|
|
1177
|
-
*
|
|
1178
|
-
* Creates a shared NATS connection, codec, event bus, and optionally
|
|
1179
|
-
* the full consumer infrastructure (streams, consumers, routers).
|
|
1180
|
-
*
|
|
1181
|
-
* @param options Module configuration.
|
|
1182
|
-
* @returns Dynamic module ready to be imported.
|
|
1183
|
-
*/
|
|
1184
|
-
static forRoot(options: JetstreamModuleOptions): DynamicModule;
|
|
1185
|
-
/**
|
|
1186
|
-
* Register the JetStream transport globally with async configuration.
|
|
1187
|
-
*
|
|
1188
|
-
* Supports `useFactory`, `useExisting`, and `useClass` patterns
|
|
1189
|
-
* for loading configuration from ConfigService, environment, etc.
|
|
1190
|
-
*
|
|
1191
|
-
* @param asyncOptions Async configuration.
|
|
1192
|
-
* @returns Dynamic module ready to be imported.
|
|
1193
|
-
*/
|
|
1194
|
-
static forRootAsync(asyncOptions: JetstreamModuleAsyncOptions): DynamicModule;
|
|
1195
|
-
/**
|
|
1196
|
-
* Register a lightweight client proxy for a target service.
|
|
1197
|
-
*
|
|
1198
|
-
* Reuses the shared NATS connection from `forRoot()`.
|
|
1199
|
-
* Import in each feature module that needs to communicate with a specific service.
|
|
1200
|
-
*
|
|
1201
|
-
* @param options Feature options with target service name.
|
|
1202
|
-
* @returns Dynamic module with the client provider.
|
|
1203
|
-
*/
|
|
1204
|
-
static forFeature(options: JetstreamFeatureOptions): DynamicModule;
|
|
1205
|
-
private static createCoreProviders;
|
|
1206
|
-
/** Create providers that depend on JETSTREAM_OPTIONS (shared by sync and async). */
|
|
1207
|
-
private static createCoreDependentProviders;
|
|
1208
|
-
/** Create async options provider from useFactory/useExisting/useClass. */
|
|
1209
|
-
private static createAsyncOptionsProvider;
|
|
1210
|
-
/**
|
|
1211
|
-
* Gracefully shut down the transport on application termination.
|
|
1212
|
-
*/
|
|
1213
|
-
onApplicationShutdown(): Promise<void>;
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
/**
|
|
1217
|
-
* NestJS ClientProxy implementation for the JetStream transport.
|
|
1218
|
-
*
|
|
1219
|
-
* Supports two operational modes:
|
|
1220
|
-
* - **Core mode** (default): Uses `nc.request()` for RPC, `nc.publish()` for events.
|
|
1221
|
-
* - **JetStream mode**: Uses `js.publish()` for RPC commands + inbox for responses.
|
|
1222
|
-
*
|
|
1223
|
-
* Events always go through JetStream publish for guaranteed delivery.
|
|
1224
|
-
* The mode only affects RPC (request/reply) behavior.
|
|
1225
|
-
*
|
|
1226
|
-
* Clients are lightweight — they share the NATS connection from `forRoot()`.
|
|
1227
|
-
*/
|
|
1228
|
-
declare class JetstreamClient extends ClientProxy {
|
|
1229
|
-
private readonly rootOptions;
|
|
1230
|
-
private readonly connection;
|
|
1231
|
-
private readonly codec;
|
|
1232
|
-
private readonly eventBus;
|
|
1233
|
-
private readonly logger;
|
|
1234
|
-
/** Target service name this client sends messages to. */
|
|
1235
|
-
private readonly targetName;
|
|
1236
|
-
/** Pre-cached caller name derived from rootOptions.name, computed once in constructor. */
|
|
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;
|
|
1253
|
-
/** Shared inbox for JetStream-mode RPC responses. */
|
|
1254
|
-
private inbox;
|
|
1255
|
-
private inboxSubscription;
|
|
1256
|
-
/** Pending JetStream-mode RPC callbacks, keyed by correlation ID. */
|
|
1257
|
-
private readonly pendingMessages;
|
|
1258
|
-
/** Pending JetStream-mode RPC timeouts, keyed by correlation ID. */
|
|
1259
|
-
private readonly pendingTimeouts;
|
|
1260
|
-
/** Subscription to connection status events for disconnect handling. */
|
|
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;
|
|
1268
|
-
constructor(rootOptions: JetstreamModuleOptions, targetServiceName: string, connection: ConnectionProvider, codec: Codec, eventBus: EventBus);
|
|
1269
|
-
/**
|
|
1270
|
-
* Establish connection. Called automatically by NestJS on first use.
|
|
1271
|
-
*
|
|
1272
|
-
* Sets up the JetStream RPC inbox (if in JetStream mode) and subscribes
|
|
1273
|
-
* to connection status events for fail-fast disconnect handling.
|
|
1274
|
-
*
|
|
1275
|
-
* @returns The underlying NATS connection.
|
|
1276
|
-
*/
|
|
1277
|
-
connect(): Promise<NatsConnection>;
|
|
1278
|
-
/** Clean up resources: reject pending RPCs, unsubscribe from status events. */
|
|
1279
|
-
close(): Promise<void>;
|
|
1280
|
-
/**
|
|
1281
|
-
* Direct access to the raw NATS connection.
|
|
1282
|
-
*
|
|
1283
|
-
* @throws Error if not connected.
|
|
1284
|
-
*/
|
|
1285
|
-
unwrap<T = NatsConnection>(): T;
|
|
1286
|
-
/**
|
|
1287
|
-
* Publish a fire-and-forget event to JetStream.
|
|
1288
|
-
*
|
|
1289
|
-
* Events are published to either the workqueue stream or broadcast stream
|
|
1290
|
-
* depending on the subject prefix. When a schedule is present the message
|
|
1291
|
-
* is published to a `_sch` subject within the same stream, with the target
|
|
1292
|
-
* set to the original event subject.
|
|
1293
|
-
*/
|
|
1294
|
-
protected dispatchEvent<T = unknown>(packet: ReadPacket): Promise<T>;
|
|
1295
|
-
/**
|
|
1296
|
-
* Publish an RPC command and register callback for response.
|
|
1297
|
-
*
|
|
1298
|
-
* Core mode: uses nc.request() with timeout.
|
|
1299
|
-
* JetStream mode: publishes to stream + waits for inbox response.
|
|
1666
|
+
* Stores callbacks for client use. Primary lifecycle events
|
|
1667
|
+
* are routed through EventBus.
|
|
1300
1668
|
*/
|
|
1301
|
-
|
|
1302
|
-
/** Core mode: nc.request() with timeout. */
|
|
1303
|
-
private publishCoreRpc;
|
|
1304
|
-
/** JetStream mode: publish to stream + wait for inbox response. */
|
|
1305
|
-
private publishJetStreamRpc;
|
|
1306
|
-
/** Fail-fast all pending JetStream RPC callbacks on connection loss. */
|
|
1307
|
-
private handleDisconnect;
|
|
1308
|
-
/** Reject all pending RPC callbacks, clear timeouts, and tear down inbox. */
|
|
1309
|
-
private rejectPendingRpcs;
|
|
1310
|
-
/** Setup shared inbox subscription for JetStream RPC responses. */
|
|
1311
|
-
private setupInbox;
|
|
1312
|
-
/** Route an inbox reply to the matching pending callback. */
|
|
1313
|
-
private routeInboxReply;
|
|
1669
|
+
on(event: string, callback: Function): void;
|
|
1314
1670
|
/**
|
|
1315
|
-
*
|
|
1316
|
-
* between the event, broadcast, and ordered prefixes.
|
|
1671
|
+
* Unwrap the underlying NATS connection.
|
|
1317
1672
|
*
|
|
1318
|
-
*
|
|
1319
|
-
* patterns that cannot possibly carry a broadcast/ordered marker, which is
|
|
1320
|
-
* the overwhelmingly common case.
|
|
1673
|
+
* @throws Error if the transport has not started.
|
|
1321
1674
|
*/
|
|
1322
|
-
|
|
1323
|
-
/**
|
|
1324
|
-
|
|
1325
|
-
/**
|
|
1326
|
-
private
|
|
1675
|
+
unwrap<T>(): T;
|
|
1676
|
+
/** Access the pattern registry (for module-level introspection). */
|
|
1677
|
+
getPatternRegistry(): PatternRegistry;
|
|
1678
|
+
/** Determine which streams and durable consumers are needed. */
|
|
1679
|
+
private resolveRequiredKinds;
|
|
1680
|
+
/** Populate the shared ack_wait map from actual NATS consumer configs. */
|
|
1681
|
+
private populateAckWaitMap;
|
|
1682
|
+
/** Build max_deliver map from actual NATS consumer configs (not options). */
|
|
1683
|
+
private buildMaxDeliverMap;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
/** Minimal interface for anything that can be stopped during shutdown. */
|
|
1687
|
+
interface Stoppable {
|
|
1688
|
+
close(): void;
|
|
1689
|
+
}
|
|
1690
|
+
/**
|
|
1691
|
+
* Orchestrates graceful transport shutdown.
|
|
1692
|
+
*
|
|
1693
|
+
* Shutdown sequence:
|
|
1694
|
+
* 1. Emit onShutdownStart hook
|
|
1695
|
+
* 2. Stop accepting new messages (close subscriptions, stop consumers)
|
|
1696
|
+
* 3. Drain and close NATS connection (with timeout safety net)
|
|
1697
|
+
* 4. Emit onShutdownComplete hook
|
|
1698
|
+
*
|
|
1699
|
+
* Idempotent — concurrent or repeated calls return the same promise.
|
|
1700
|
+
* This is critical because NestJS may call `onApplicationShutdown` on
|
|
1701
|
+
* multiple module instances (forRoot + forFeature) that share this
|
|
1702
|
+
* singleton, and the call order is not guaranteed.
|
|
1703
|
+
*/
|
|
1704
|
+
declare class ShutdownManager {
|
|
1705
|
+
private readonly connection;
|
|
1706
|
+
private readonly eventBus;
|
|
1707
|
+
private readonly timeout;
|
|
1708
|
+
private readonly logger;
|
|
1709
|
+
private shutdownPromise?;
|
|
1710
|
+
constructor(connection: ConnectionProvider, eventBus: EventBus, timeout: number);
|
|
1327
1711
|
/**
|
|
1328
|
-
*
|
|
1712
|
+
* Execute the full shutdown sequence.
|
|
1329
1713
|
*
|
|
1330
|
-
*
|
|
1331
|
-
* uses a separate `_sch` namespace that is NOT matched by any consumer filter.
|
|
1332
|
-
* NATS holds the message and publishes it to the target subject after the delay.
|
|
1714
|
+
* Idempotent — concurrent or repeated calls return the same promise.
|
|
1333
1715
|
*
|
|
1334
|
-
*
|
|
1335
|
-
* - `{svc}__microservice.ev.order.reminder` → `{svc}__microservice._sch.order.reminder`
|
|
1336
|
-
* - `broadcast.config.updated` → `broadcast._sch.config.updated`
|
|
1716
|
+
* @param strategy Optional stoppable to close (stops consumers and subscriptions).
|
|
1337
1717
|
*/
|
|
1338
|
-
|
|
1718
|
+
shutdown(strategy?: Stoppable): Promise<void>;
|
|
1719
|
+
private doShutdown;
|
|
1339
1720
|
}
|
|
1340
1721
|
|
|
1341
1722
|
/**
|
|
1342
|
-
*
|
|
1723
|
+
* Root module for the NestJS JetStream transport.
|
|
1343
1724
|
*
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1725
|
+
* - `forRoot()` / `forRootAsync()` — registers once in AppModule.
|
|
1726
|
+
* Creates shared NATS connection, codec, event bus, and optionally
|
|
1727
|
+
* the consumer infrastructure.
|
|
1728
|
+
*
|
|
1729
|
+
* - `forFeature()` — registers in feature modules.
|
|
1730
|
+
* Creates a lightweight client proxy targeting a specific service.
|
|
1346
1731
|
*
|
|
1347
1732
|
* @example
|
|
1348
1733
|
* ```typescript
|
|
1349
|
-
*
|
|
1350
|
-
*
|
|
1351
|
-
*
|
|
1352
|
-
*
|
|
1734
|
+
* // AppModule — global setup
|
|
1735
|
+
* @Module({
|
|
1736
|
+
* imports: [
|
|
1737
|
+
* JetstreamModule.forRoot({
|
|
1738
|
+
* name: 'orders',
|
|
1739
|
+
* servers: ['nats://localhost:4222'],
|
|
1740
|
+
* }),
|
|
1741
|
+
* ],
|
|
1742
|
+
* })
|
|
1743
|
+
* export class AppModule {}
|
|
1353
1744
|
*
|
|
1354
|
-
*
|
|
1745
|
+
* // Feature module — per-service clients
|
|
1746
|
+
* @Module({
|
|
1747
|
+
* imports: [
|
|
1748
|
+
* JetstreamModule.forFeature({ name: 'users' }),
|
|
1749
|
+
* JetstreamModule.forFeature({ name: 'payments' }),
|
|
1750
|
+
* ],
|
|
1751
|
+
* })
|
|
1752
|
+
* export class OrdersModule {}
|
|
1355
1753
|
* ```
|
|
1356
1754
|
*/
|
|
1357
|
-
declare class
|
|
1358
|
-
|
|
1359
|
-
readonly
|
|
1360
|
-
|
|
1361
|
-
readonly headers: ReadonlyMap<string, string>;
|
|
1362
|
-
/** Per-request RPC timeout override in ms. */
|
|
1363
|
-
readonly timeout?: number | undefined;
|
|
1364
|
-
/** Custom message ID for JetStream deduplication. */
|
|
1365
|
-
readonly messageId?: string | undefined;
|
|
1366
|
-
/** Schedule options for delayed delivery. */
|
|
1367
|
-
readonly schedule?: ScheduleRecordOptions | undefined;
|
|
1368
|
-
/** Per-message TTL as Go duration string (e.g. "30s", "5m"). */
|
|
1369
|
-
readonly ttl?: string | undefined;
|
|
1370
|
-
constructor(
|
|
1371
|
-
/** Message payload. */
|
|
1372
|
-
data: TData,
|
|
1373
|
-
/** Custom headers set via {@link JetstreamRecordBuilder.setHeader}. */
|
|
1374
|
-
headers: ReadonlyMap<string, string>,
|
|
1375
|
-
/** Per-request RPC timeout override in ms. */
|
|
1376
|
-
timeout?: number | undefined,
|
|
1377
|
-
/** Custom message ID for JetStream deduplication. */
|
|
1378
|
-
messageId?: string | undefined,
|
|
1379
|
-
/** Schedule options for delayed delivery. */
|
|
1380
|
-
schedule?: ScheduleRecordOptions | undefined,
|
|
1381
|
-
/** Per-message TTL as Go duration string (e.g. "30s", "5m"). */
|
|
1382
|
-
ttl?: string | undefined);
|
|
1383
|
-
}
|
|
1384
|
-
/**
|
|
1385
|
-
* Fluent builder for constructing JetstreamRecord instances.
|
|
1386
|
-
*
|
|
1387
|
-
* Protected headers (`correlation-id`, `reply-to`, `error`) cannot be
|
|
1388
|
-
* set by the user — attempting to do so throws an error at build time.
|
|
1389
|
-
*/
|
|
1390
|
-
declare class JetstreamRecordBuilder<TData = unknown> {
|
|
1391
|
-
private data;
|
|
1392
|
-
private readonly headers;
|
|
1393
|
-
private timeout;
|
|
1394
|
-
private messageId;
|
|
1395
|
-
private scheduleOptions;
|
|
1396
|
-
private ttlDuration;
|
|
1397
|
-
constructor(data?: TData);
|
|
1398
|
-
/**
|
|
1399
|
-
* Set the message payload.
|
|
1400
|
-
*
|
|
1401
|
-
* @param data - Payload to serialize via the configured {@link Codec}.
|
|
1402
|
-
*/
|
|
1403
|
-
setData(data: TData): this;
|
|
1404
|
-
/**
|
|
1405
|
-
* Set a single custom header.
|
|
1406
|
-
*
|
|
1407
|
-
* @param key - Header name (e.g. `'x-tenant'`).
|
|
1408
|
-
* @param value - Header value.
|
|
1409
|
-
* @throws Error if the header name is reserved by the transport.
|
|
1410
|
-
*/
|
|
1411
|
-
setHeader(key: string, value: string): this;
|
|
1412
|
-
/**
|
|
1413
|
-
* Set multiple custom headers at once.
|
|
1414
|
-
*
|
|
1415
|
-
* @param headers - Key-value pairs to set as headers.
|
|
1416
|
-
* @throws Error if any header name is reserved by the transport.
|
|
1417
|
-
*/
|
|
1418
|
-
setHeaders(headers: Record<string, string>): this;
|
|
1755
|
+
declare class JetstreamModule implements OnApplicationShutdown {
|
|
1756
|
+
private readonly shutdownManager?;
|
|
1757
|
+
private readonly strategy?;
|
|
1758
|
+
constructor(shutdownManager?: ShutdownManager | undefined, strategy?: (JetstreamStrategy | null) | undefined);
|
|
1419
1759
|
/**
|
|
1420
|
-
*
|
|
1421
|
-
*
|
|
1422
|
-
* NATS JetStream uses this ID to detect duplicate publishes within the
|
|
1423
|
-
* stream's `duplicate_window`. If two messages with the same ID arrive
|
|
1424
|
-
* within the window, the second is silently dropped.
|
|
1425
|
-
*
|
|
1426
|
-
* When not set, a random UUID is generated automatically.
|
|
1427
|
-
*
|
|
1428
|
-
* @param id - Unique message identifier (e.g. order ID, idempotency key).
|
|
1760
|
+
* Register the JetStream transport globally.
|
|
1429
1761
|
*
|
|
1430
|
-
*
|
|
1431
|
-
*
|
|
1432
|
-
* new JetstreamRecordBuilder(data)
|
|
1433
|
-
* .setMessageId(`order-${order.id}`)
|
|
1434
|
-
* .build();
|
|
1435
|
-
* ```
|
|
1436
|
-
*/
|
|
1437
|
-
setMessageId(id: string): this;
|
|
1438
|
-
/**
|
|
1439
|
-
* Set per-request RPC timeout.
|
|
1762
|
+
* Creates a shared NATS connection, codec, event bus, and optionally
|
|
1763
|
+
* the full consumer infrastructure (streams, consumers, routers).
|
|
1440
1764
|
*
|
|
1441
|
-
* @param
|
|
1765
|
+
* @param options Module configuration.
|
|
1766
|
+
* @returns Dynamic module ready to be imported.
|
|
1442
1767
|
*/
|
|
1443
|
-
|
|
1768
|
+
static forRoot(options: JetstreamModuleOptions): DynamicModule;
|
|
1444
1769
|
/**
|
|
1445
|
-
*
|
|
1446
|
-
*
|
|
1447
|
-
* The message is held by NATS and delivered to the event consumer
|
|
1448
|
-
* at the specified time. Requires NATS >= 2.12 and `allow_msg_schedules: true`
|
|
1449
|
-
* on the event stream (via `events: { stream: { allow_msg_schedules: true } }`).
|
|
1770
|
+
* Register the JetStream transport globally with async configuration.
|
|
1450
1771
|
*
|
|
1451
|
-
*
|
|
1452
|
-
*
|
|
1772
|
+
* Supports `useFactory`, `useExisting`, and `useClass` patterns
|
|
1773
|
+
* for loading configuration from ConfigService, environment, etc.
|
|
1453
1774
|
*
|
|
1454
|
-
* @param
|
|
1455
|
-
* @
|
|
1775
|
+
* @param asyncOptions Async configuration.
|
|
1776
|
+
* @returns Dynamic module ready to be imported.
|
|
1456
1777
|
*/
|
|
1457
|
-
|
|
1778
|
+
static forRootAsync(asyncOptions: JetstreamModuleAsyncOptions): DynamicModule;
|
|
1458
1779
|
/**
|
|
1459
|
-
*
|
|
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.
|
|
1780
|
+
* Register a lightweight client proxy for a target service.
|
|
1469
1781
|
*
|
|
1470
|
-
*
|
|
1471
|
-
*
|
|
1472
|
-
* import { toNanos } from '@horizon-republic/nestjs-jetstream';
|
|
1782
|
+
* Reuses the shared NATS connection from `forRoot()`.
|
|
1783
|
+
* Import in each feature module that needs to communicate with a specific service.
|
|
1473
1784
|
*
|
|
1474
|
-
*
|
|
1475
|
-
*
|
|
1476
|
-
* ```
|
|
1785
|
+
* @param options Feature options with target service name.
|
|
1786
|
+
* @returns Dynamic module with the client provider.
|
|
1477
1787
|
*/
|
|
1478
|
-
|
|
1788
|
+
static forFeature(options: JetstreamFeatureOptions): DynamicModule;
|
|
1789
|
+
private static createCoreProviders;
|
|
1790
|
+
/** Create providers that depend on JETSTREAM_OPTIONS (shared by sync and async). */
|
|
1791
|
+
private static createCoreDependentProviders;
|
|
1792
|
+
/** Create async options provider from useFactory/useExisting/useClass. */
|
|
1793
|
+
private static createAsyncOptionsProvider;
|
|
1479
1794
|
/**
|
|
1480
|
-
*
|
|
1481
|
-
*
|
|
1482
|
-
* @returns A frozen record ready to pass to `client.send()` or `client.emit()`.
|
|
1795
|
+
* Gracefully shut down the transport on application termination.
|
|
1483
1796
|
*/
|
|
1484
|
-
|
|
1485
|
-
/** Validate that a header key is not reserved. */
|
|
1486
|
-
private validateHeaderKey;
|
|
1797
|
+
onApplicationShutdown(): Promise<void>;
|
|
1487
1798
|
}
|
|
1488
1799
|
|
|
1489
1800
|
/**
|
|
@@ -1873,4 +2184,4 @@ declare const isJetStreamRpcMode: (rpc: RpcConfig | undefined) => boolean;
|
|
|
1873
2184
|
/** Check if the RPC config specifies Core mode (default). */
|
|
1874
2185
|
declare const isCoreRpcMode: (rpc: RpcConfig | undefined) => boolean;
|
|
1875
2186
|
|
|
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 };
|
|
2187
|
+
export { type CaptureBodyOptions, type Codec, ConsumeKind, type ConsumeSourceMsg, 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, DEFAULT_TRACES, type DeadLetterInfo, type ErrorClassification, type HandlerMetadata, JETSTREAM_CODEC, JETSTREAM_CONNECTION, JETSTREAM_OPTIONS, JetstreamClient, type JetstreamConsumeContext, JetstreamDlqHeader, type JetstreamFeatureOptions, JetstreamHeader, JetstreamHealthIndicator, type JetstreamHealthStatus, JetstreamModule, type JetstreamModuleAsyncOptions, type JetstreamModuleOptions, type JetstreamPublishContext, JetstreamRecord, JetstreamRecordBuilder, type JetstreamResponseContext, JetstreamStrategy, JetstreamTrace, JsonCodec, MIN_METADATA_TTL, MessageKind, type MetadataRegistryOptions, MsgpackCodec, NatsErrorCode, type OrderedEventOverrides, type OtelOptions, PatternPrefix, PublishKind, RESERVED_HEADERS, type RpcConfig, RpcContext, type ScheduleRecordOptions, type ServerEndpoint, type StreamConfigOverrides, type StreamConsumerOverrides, StreamKind, TRACER_NAME, TransportEvent, type TransportHooks, buildBroadcastSubject, buildSubject, consumerName, dlqStreamName, getClientToken, internalName, isCoreRpcMode, isJetStreamRpcMode, metadataKey, streamName, toNanos };
|