@horizon-republic/nestjs-jetstream 2.2.0 → 2.3.2
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 +129 -80
- package/dist/index.cjs +2068 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +995 -0
- package/dist/index.d.ts +995 -13
- package/dist/index.js +2068 -39
- package/dist/index.js.map +1 -1
- package/package.json +29 -19
- package/dist/client/index.d.ts +0 -3
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -9
- package/dist/client/index.js.map +0 -1
- package/dist/client/jetstream.client.d.ts +0 -76
- package/dist/client/jetstream.client.d.ts.map +0 -1
- package/dist/client/jetstream.client.js +0 -325
- package/dist/client/jetstream.client.js.map +0 -1
- package/dist/client/jetstream.record.d.ts +0 -55
- package/dist/client/jetstream.record.d.ts.map +0 -1
- package/dist/client/jetstream.record.js +0 -84
- package/dist/client/jetstream.record.js.map +0 -1
- package/dist/codec/index.d.ts +0 -2
- package/dist/codec/index.d.ts.map +0 -1
- package/dist/codec/index.js +0 -6
- package/dist/codec/index.js.map +0 -1
- package/dist/codec/json.codec.d.ts +0 -20
- package/dist/codec/json.codec.d.ts.map +0 -1
- package/dist/codec/json.codec.js +0 -30
- package/dist/codec/json.codec.js.map +0 -1
- package/dist/connection/connection.provider.d.ts +0 -50
- package/dist/connection/connection.provider.d.ts.map +0 -1
- package/dist/connection/connection.provider.js +0 -141
- package/dist/connection/connection.provider.js.map +0 -1
- package/dist/connection/index.d.ts +0 -2
- package/dist/connection/index.d.ts.map +0 -1
- package/dist/connection/index.js +0 -6
- package/dist/connection/index.js.map +0 -1
- package/dist/context/index.d.ts +0 -2
- package/dist/context/index.d.ts.map +0 -1
- package/dist/context/index.js +0 -6
- package/dist/context/index.js.map +0 -1
- package/dist/context/rpc.context.d.ts +0 -35
- package/dist/context/rpc.context.d.ts.map +0 -1
- package/dist/context/rpc.context.js +0 -44
- package/dist/context/rpc.context.js.map +0 -1
- package/dist/health/index.d.ts +0 -3
- package/dist/health/index.d.ts.map +0 -1
- package/dist/health/index.js +0 -6
- package/dist/health/index.js.map +0 -1
- package/dist/health/jetstream.health-indicator.d.ts +0 -47
- package/dist/health/jetstream.health-indicator.d.ts.map +0 -1
- package/dist/health/jetstream.health-indicator.js +0 -85
- package/dist/health/jetstream.health-indicator.js.map +0 -1
- package/dist/hooks/event-bus.d.ts +0 -31
- package/dist/hooks/event-bus.d.ts.map +0 -1
- package/dist/hooks/event-bus.js +0 -79
- package/dist/hooks/event-bus.js.map +0 -1
- package/dist/hooks/index.d.ts +0 -2
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js +0 -6
- package/dist/hooks/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/interfaces/client.interface.d.ts +0 -14
- package/dist/interfaces/client.interface.d.ts.map +0 -1
- package/dist/interfaces/client.interface.js +0 -3
- package/dist/interfaces/client.interface.js.map +0 -1
- package/dist/interfaces/codec.interface.d.ts +0 -28
- package/dist/interfaces/codec.interface.d.ts.map +0 -1
- package/dist/interfaces/codec.interface.js +0 -3
- package/dist/interfaces/codec.interface.js.map +0 -1
- package/dist/interfaces/hooks.interface.d.ts +0 -71
- package/dist/interfaces/hooks.interface.d.ts.map +0 -1
- package/dist/interfaces/hooks.interface.js +0 -16
- package/dist/interfaces/hooks.interface.js.map +0 -1
- package/dist/interfaces/index.d.ts +0 -8
- package/dist/interfaces/index.d.ts.map +0 -1
- package/dist/interfaces/index.js +0 -6
- package/dist/interfaces/index.js.map +0 -1
- package/dist/interfaces/options.interface.d.ts +0 -142
- package/dist/interfaces/options.interface.d.ts.map +0 -1
- package/dist/interfaces/options.interface.js +0 -3
- package/dist/interfaces/options.interface.js.map +0 -1
- package/dist/interfaces/routing.interface.d.ts +0 -15
- package/dist/interfaces/routing.interface.d.ts.map +0 -1
- package/dist/interfaces/routing.interface.js +0 -3
- package/dist/interfaces/routing.interface.js.map +0 -1
- package/dist/interfaces/stream.interface.d.ts +0 -5
- package/dist/interfaces/stream.interface.d.ts.map +0 -1
- package/dist/interfaces/stream.interface.js +0 -3
- package/dist/interfaces/stream.interface.js.map +0 -1
- package/dist/jetstream.constants.d.ts +0 -58
- package/dist/jetstream.constants.d.ts.map +0 -1
- package/dist/jetstream.constants.js +0 -168
- package/dist/jetstream.constants.js.map +0 -1
- package/dist/jetstream.module.d.ts +0 -89
- package/dist/jetstream.module.d.ts.map +0 -1
- package/dist/jetstream.module.js +0 -410
- package/dist/jetstream.module.js.map +0 -1
- package/dist/server/core-rpc.server.d.ts +0 -31
- package/dist/server/core-rpc.server.d.ts.map +0 -1
- package/dist/server/core-rpc.server.js +0 -95
- package/dist/server/core-rpc.server.js.map +0 -1
- package/dist/server/index.d.ts +0 -5
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js +0 -16
- package/dist/server/index.js.map +0 -1
- package/dist/server/infrastructure/consumer.provider.d.ts +0 -36
- package/dist/server/infrastructure/consumer.provider.d.ts.map +0 -1
- package/dist/server/infrastructure/consumer.provider.js +0 -123
- package/dist/server/infrastructure/consumer.provider.js.map +0 -1
- package/dist/server/infrastructure/index.d.ts +0 -4
- package/dist/server/infrastructure/index.d.ts.map +0 -1
- package/dist/server/infrastructure/index.js +0 -10
- package/dist/server/infrastructure/index.js.map +0 -1
- package/dist/server/infrastructure/message.provider.d.ts +0 -46
- package/dist/server/infrastructure/message.provider.d.ts.map +0 -1
- package/dist/server/infrastructure/message.provider.js +0 -100
- package/dist/server/infrastructure/message.provider.js.map +0 -1
- package/dist/server/infrastructure/stream.provider.d.ts +0 -38
- package/dist/server/infrastructure/stream.provider.d.ts.map +0 -1
- package/dist/server/infrastructure/stream.provider.js +0 -109
- package/dist/server/infrastructure/stream.provider.js.map +0 -1
- package/dist/server/routing/event.router.d.ts +0 -56
- package/dist/server/routing/event.router.d.ts.map +0 -1
- package/dist/server/routing/event.router.js +0 -132
- package/dist/server/routing/event.router.js.map +0 -1
- package/dist/server/routing/index.d.ts +0 -5
- package/dist/server/routing/index.d.ts.map +0 -1
- package/dist/server/routing/index.js +0 -10
- package/dist/server/routing/index.js.map +0 -1
- package/dist/server/routing/pattern-registry.d.ts +0 -39
- package/dist/server/routing/pattern-registry.d.ts.map +0 -1
- package/dist/server/routing/pattern-registry.js +0 -116
- package/dist/server/routing/pattern-registry.js.map +0 -1
- package/dist/server/routing/rpc.router.d.ts +0 -37
- package/dist/server/routing/rpc.router.d.ts.map +0 -1
- package/dist/server/routing/rpc.router.js +0 -121
- package/dist/server/routing/rpc.router.js.map +0 -1
- package/dist/server/strategy.d.ts +0 -55
- package/dist/server/strategy.d.ts.map +0 -1
- package/dist/server/strategy.js +0 -113
- package/dist/server/strategy.js.map +0 -1
- package/dist/shutdown/index.d.ts +0 -2
- package/dist/shutdown/index.d.ts.map +0 -1
- package/dist/shutdown/index.js +0 -6
- package/dist/shutdown/index.js.map +0 -1
- package/dist/shutdown/shutdown.manager.d.ts +0 -27
- package/dist/shutdown/shutdown.manager.d.ts.map +0 -1
- package/dist/shutdown/shutdown.manager.js +0 -45
- package/dist/shutdown/shutdown.manager.js.map +0 -1
- package/dist/utils/index.d.ts +0 -3
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -8
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/serialize-error.d.ts +0 -10
- package/dist/utils/serialize-error.d.ts.map +0 -1
- package/dist/utils/serialize-error.js +0 -21
- package/dist/utils/serialize-error.js.map +0 -1
- package/dist/utils/unwrap-result.d.ts +0 -15
- package/dist/utils/unwrap-result.d.ts.map +0 -1
- package/dist/utils/unwrap-result.js +0 -49
- package/dist/utils/unwrap-result.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/jetstream.module.ts","../src/client/jetstream.client.ts","../src/interfaces/hooks.interface.ts","../src/jetstream.constants.ts","../src/client/jetstream.record.ts","../src/codec/json.codec.ts","../src/connection/connection.provider.ts","../src/hooks/event-bus.ts","../src/health/jetstream.health-indicator.ts","../src/server/strategy.ts","../src/server/core-rpc.server.ts","../src/context/rpc.context.ts","../src/utils/serialize-error.ts","../src/utils/unwrap-result.ts","../src/server/infrastructure/stream.provider.ts","../src/server/infrastructure/consumer.provider.ts","../src/server/infrastructure/message.provider.ts","../src/server/routing/pattern-registry.ts","../src/server/routing/event.router.ts","../src/server/routing/rpc.router.ts","../src/shutdown/shutdown.manager.ts"],"sourcesContent":["// Module\nexport { JetstreamModule } from './jetstream.module';\n\n// Interfaces\nexport { TransportEvent } from './interfaces';\n\nexport type {\n Codec,\n DeadLetterInfo,\n JetstreamFeatureOptions,\n JetstreamModuleAsyncOptions,\n JetstreamModuleOptions,\n RpcConfig,\n StreamConsumerOverrides,\n TransportHooks,\n} from './interfaces';\n\n// Client\nexport { JetstreamClient } from './client';\n\nexport { JetstreamRecord, JetstreamRecordBuilder } from './client';\n\n// Codec\nexport { JsonCodec } from './codec';\n\n// Context\nexport { RpcContext } from './context';\n\n// Health\nexport { JetstreamHealthIndicator } from './health';\n\nexport type { JetstreamHealthStatus } from './health';\n\n// Constants (selective — only what users need)\nexport {\n getClientToken,\n JetstreamHeader,\n JETSTREAM_CODEC,\n JETSTREAM_CONNECTION,\n JETSTREAM_EVENT_BUS,\n JETSTREAM_OPTIONS,\n nanos,\n} from './jetstream.constants';\n\n// Hooks\nexport { EventBus } from './hooks';\n\n// Server (for advanced use cases)\nexport { JetstreamStrategy } from './server';\n","import {\n DynamicModule,\n Global,\n Inject,\n Logger,\n Module,\n OnApplicationShutdown,\n Optional,\n Provider,\n} from '@nestjs/common';\n\nimport { JetstreamClient } from './client';\nimport { JsonCodec } from './codec';\nimport { ConnectionProvider } from './connection';\nimport { EventBus } from './hooks';\nimport { JetstreamHealthIndicator } from './health';\nimport type {\n Codec,\n JetstreamFeatureOptions,\n JetstreamModuleAsyncOptions,\n JetstreamModuleOptions,\n} from './interfaces';\nimport {\n DEFAULT_BROADCAST_CONSUMER_CONFIG,\n DEFAULT_EVENT_CONSUMER_CONFIG,\n DEFAULT_SHUTDOWN_TIMEOUT,\n getClientToken,\n JETSTREAM_CODEC,\n JETSTREAM_CONNECTION,\n JETSTREAM_EVENT_BUS,\n JETSTREAM_OPTIONS,\n streamName,\n} from './jetstream.constants';\nimport {\n CoreRpcServer,\n ConsumerProvider,\n EventRouter,\n JetstreamStrategy,\n MessageProvider,\n PatternRegistry,\n RpcRouter,\n StreamProvider,\n} from './server';\nimport type { DeadLetterConfig } from './server';\nimport { ShutdownManager } from './shutdown';\n\n/**\n * Root module for the NestJS JetStream transport.\n *\n * - `forRoot()` / `forRootAsync()` — registers once in AppModule.\n * Creates shared NATS connection, codec, event bus, and optionally\n * the consumer infrastructure.\n *\n * - `forFeature()` — registers in feature modules.\n * Creates a lightweight client proxy targeting a specific service.\n *\n * @example\n * ```typescript\n * // AppModule — global setup\n * @Module({\n * imports: [\n * JetstreamModule.forRoot({\n * name: 'orders',\n * servers: ['nats://localhost:4222'],\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * // Feature module — per-service clients\n * @Module({\n * imports: [\n * JetstreamModule.forFeature({ name: 'users' }),\n * JetstreamModule.forFeature({ name: 'payments' }),\n * ],\n * })\n * export class OrdersModule {}\n * ```\n */\n@Global()\n@Module({})\nexport class JetstreamModule implements OnApplicationShutdown {\n public constructor(\n @Optional()\n @Inject(ShutdownManager)\n private readonly shutdownManager?: ShutdownManager,\n @Optional() @Inject(JetstreamStrategy) private readonly strategy?: JetstreamStrategy | null,\n ) {}\n\n // -------------------------------------------------------------------\n // forRoot — global module registration\n // -------------------------------------------------------------------\n\n /**\n * Register the JetStream transport globally.\n *\n * Creates a shared NATS connection, codec, event bus, and optionally\n * the full consumer infrastructure (streams, consumers, routers).\n *\n * @param options Module configuration.\n * @returns Dynamic module ready to be imported.\n */\n public static forRoot(options: JetstreamModuleOptions): DynamicModule {\n const providers = this.createCoreProviders(options);\n\n return {\n module: JetstreamModule,\n global: true,\n providers,\n exports: [\n JETSTREAM_CONNECTION,\n JETSTREAM_CODEC,\n JETSTREAM_EVENT_BUS,\n JETSTREAM_OPTIONS,\n ShutdownManager,\n JetstreamStrategy,\n JetstreamHealthIndicator,\n ],\n };\n }\n\n // -------------------------------------------------------------------\n // forRootAsync — async global module registration\n // -------------------------------------------------------------------\n\n /**\n * Register the JetStream transport globally with async configuration.\n *\n * Supports `useFactory`, `useExisting`, and `useClass` patterns\n * for loading configuration from ConfigService, environment, etc.\n *\n * @param asyncOptions Async configuration.\n * @returns Dynamic module ready to be imported.\n */\n public static forRootAsync(asyncOptions: JetstreamModuleAsyncOptions): DynamicModule {\n const asyncProviders = this.createAsyncOptionsProvider(asyncOptions);\n const coreProviders = this.createCoreDependentProviders();\n\n return {\n module: JetstreamModule,\n global: true,\n imports: asyncOptions.imports ?? [],\n providers: [...asyncProviders, ...coreProviders],\n exports: [\n JETSTREAM_CONNECTION,\n JETSTREAM_CODEC,\n JETSTREAM_EVENT_BUS,\n JETSTREAM_OPTIONS,\n ShutdownManager,\n JetstreamStrategy,\n JetstreamHealthIndicator,\n ],\n };\n }\n\n // -------------------------------------------------------------------\n // forFeature — per-module client registration\n // -------------------------------------------------------------------\n\n /**\n * Register a lightweight client proxy for a target service.\n *\n * Reuses the shared NATS connection from `forRoot()`.\n * Import in each feature module that needs to communicate with a specific service.\n *\n * @param options Feature options with target service name.\n * @returns Dynamic module with the client provider.\n */\n public static forFeature(options: JetstreamFeatureOptions): DynamicModule {\n const clientToken = getClientToken(options.name);\n\n const clientProvider: Provider = {\n provide: clientToken,\n inject: [JETSTREAM_OPTIONS, JETSTREAM_CONNECTION, JETSTREAM_CODEC, JETSTREAM_EVENT_BUS],\n useFactory: (\n rootOptions: JetstreamModuleOptions,\n connection: ConnectionProvider,\n rootCodec: Codec,\n eventBus: EventBus,\n ) => {\n const codec = options.codec ?? rootCodec;\n\n return new JetstreamClient(rootOptions, options.name, connection, codec, eventBus);\n },\n };\n\n return {\n module: JetstreamModule,\n providers: [clientProvider],\n exports: [clientToken],\n };\n }\n\n // -------------------------------------------------------------------\n // Provider factories\n // -------------------------------------------------------------------\n\n /** Create all providers for synchronous forRoot(). */\n /**\n * Build a map of stream name -> max_deliver for dead letter detection.\n * Each stream kind (ev, broadcast) has its own consumer config with potentially\n * different max_deliver values.\n */\n private static buildMaxDeliverMap(options: JetstreamModuleOptions): Map<string, number> {\n const map = new Map<string, number>();\n const defaultEventMax = DEFAULT_EVENT_CONSUMER_CONFIG.max_deliver ?? 3;\n const defaultBroadcastMax = DEFAULT_BROADCAST_CONSUMER_CONFIG.max_deliver ?? 3;\n\n map.set(\n streamName(options.name, 'ev'),\n options.events?.consumer?.max_deliver ?? defaultEventMax,\n );\n\n map.set(\n streamName(options.name, 'broadcast'),\n options.broadcast?.consumer?.max_deliver ?? defaultBroadcastMax,\n );\n\n return map;\n }\n\n private static createCoreProviders(options: JetstreamModuleOptions): Provider[] {\n return [\n {\n provide: JETSTREAM_OPTIONS,\n useValue: options,\n },\n ...this.createCoreDependentProviders(),\n ];\n }\n\n /** Create providers that depend on JETSTREAM_OPTIONS (shared by sync and async). */\n private static createCoreDependentProviders(): Provider[] {\n return [\n // EventBus — hook system with Logger fallback\n {\n provide: JETSTREAM_EVENT_BUS,\n inject: [JETSTREAM_OPTIONS],\n useFactory: (options: JetstreamModuleOptions): EventBus => {\n const logger = new Logger('Jetstream:Module');\n\n return new EventBus(logger, options.hooks);\n },\n },\n\n // Codec — global encode/decode\n {\n provide: JETSTREAM_CODEC,\n inject: [JETSTREAM_OPTIONS],\n useFactory: (options: JetstreamModuleOptions): Codec => {\n return options.codec ?? new JsonCodec();\n },\n },\n\n // ConnectionProvider — single NATS connection\n {\n provide: JETSTREAM_CONNECTION,\n inject: [JETSTREAM_OPTIONS, JETSTREAM_EVENT_BUS],\n useFactory: (options: JetstreamModuleOptions, eventBus: EventBus): ConnectionProvider => {\n return new ConnectionProvider(options, eventBus);\n },\n },\n\n // JetstreamHealthIndicator — health check for NATS connection\n {\n provide: JetstreamHealthIndicator,\n inject: [JETSTREAM_CONNECTION],\n useFactory: (connection: ConnectionProvider): JetstreamHealthIndicator => {\n return new JetstreamHealthIndicator(connection);\n },\n },\n\n // ShutdownManager — graceful shutdown orchestration\n {\n provide: ShutdownManager,\n inject: [JETSTREAM_CONNECTION, JETSTREAM_EVENT_BUS, JETSTREAM_OPTIONS],\n useFactory: (\n connection: ConnectionProvider,\n eventBus: EventBus,\n options: JetstreamModuleOptions,\n ): ShutdownManager => {\n return new ShutdownManager(\n connection,\n eventBus,\n options.shutdownTimeout ?? DEFAULT_SHUTDOWN_TIMEOUT,\n );\n },\n },\n\n // ---------------------------------------------------------------\n // Consumer infrastructure — only created when consumer !== false.\n // Providers return null when consumer is disabled (publisher-only mode).\n // ---------------------------------------------------------------\n\n // PatternRegistry — subject-to-handler mapping\n {\n provide: PatternRegistry,\n inject: [JETSTREAM_OPTIONS],\n useFactory: (options: JetstreamModuleOptions): PatternRegistry | null => {\n if (options.consumer === false) return null;\n\n return new PatternRegistry(options);\n },\n },\n\n // StreamProvider — JetStream stream lifecycle\n {\n provide: StreamProvider,\n inject: [JETSTREAM_OPTIONS, JETSTREAM_CONNECTION],\n useFactory: (\n options: JetstreamModuleOptions,\n connection: ConnectionProvider,\n ): StreamProvider | null => {\n if (options.consumer === false) return null;\n\n return new StreamProvider(options, connection);\n },\n },\n\n // ConsumerProvider — JetStream consumer lifecycle (receives PatternRegistry for broadcast filtering)\n {\n provide: ConsumerProvider,\n inject: [JETSTREAM_OPTIONS, JETSTREAM_CONNECTION, StreamProvider, PatternRegistry],\n useFactory: (\n options: JetstreamModuleOptions,\n connection: ConnectionProvider,\n streamProvider: StreamProvider,\n patternRegistry: PatternRegistry,\n ): ConsumerProvider | null => {\n if (options.consumer === false) return null;\n\n return new ConsumerProvider(options, connection, streamProvider, patternRegistry);\n },\n },\n\n // MessageProvider — pull-based message consumption\n {\n provide: MessageProvider,\n inject: [JETSTREAM_OPTIONS, JETSTREAM_CONNECTION, JETSTREAM_EVENT_BUS],\n useFactory: (\n options: JetstreamModuleOptions,\n connection: ConnectionProvider,\n eventBus: EventBus,\n ): MessageProvider | null => {\n if (options.consumer === false) return null;\n\n return new MessageProvider(connection, eventBus);\n },\n },\n\n // EventRouter — routes event and broadcast messages to handlers\n {\n provide: EventRouter,\n inject: [\n JETSTREAM_OPTIONS,\n MessageProvider,\n PatternRegistry,\n JETSTREAM_CODEC,\n JETSTREAM_EVENT_BUS,\n ],\n useFactory: (\n options: JetstreamModuleOptions,\n messageProvider: MessageProvider,\n patternRegistry: PatternRegistry,\n codec: Codec,\n eventBus: EventBus,\n ): EventRouter | null => {\n if (options.consumer === false) return null;\n\n const deadLetterConfig: DeadLetterConfig | undefined = options.onDeadLetter\n ? {\n maxDeliverByStream: JetstreamModule.buildMaxDeliverMap(options),\n onDeadLetter: options.onDeadLetter,\n }\n : undefined;\n\n return new EventRouter(\n messageProvider,\n patternRegistry,\n codec,\n eventBus,\n deadLetterConfig,\n );\n },\n },\n\n // RpcRouter — routes RPC command messages in JetStream mode\n {\n provide: RpcRouter,\n inject: [\n JETSTREAM_OPTIONS,\n MessageProvider,\n PatternRegistry,\n JETSTREAM_CONNECTION,\n JETSTREAM_CODEC,\n JETSTREAM_EVENT_BUS,\n ],\n useFactory: (\n options: JetstreamModuleOptions,\n messageProvider: MessageProvider,\n patternRegistry: PatternRegistry,\n connection: ConnectionProvider,\n codec: Codec,\n eventBus: EventBus,\n ): RpcRouter | null => {\n if (options.consumer === false) return null;\n\n const timeout = options.rpc?.mode === 'jetstream' ? options.rpc.timeout : undefined;\n\n return new RpcRouter(\n messageProvider,\n patternRegistry,\n connection,\n codec,\n eventBus,\n timeout,\n );\n },\n },\n\n // CoreRpcServer — RPC via NATS Core request/reply\n {\n provide: CoreRpcServer,\n inject: [\n JETSTREAM_OPTIONS,\n JETSTREAM_CONNECTION,\n PatternRegistry,\n JETSTREAM_CODEC,\n JETSTREAM_EVENT_BUS,\n ],\n useFactory: (\n options: JetstreamModuleOptions,\n connection: ConnectionProvider,\n patternRegistry: PatternRegistry,\n codec: Codec,\n eventBus: EventBus,\n ): CoreRpcServer | null => {\n if (options.consumer === false) return null;\n\n return new CoreRpcServer(options, connection, patternRegistry, codec, eventBus);\n },\n },\n\n // JetstreamStrategy — server-side transport (only when consumer enabled)\n {\n provide: JetstreamStrategy,\n inject: [\n JETSTREAM_OPTIONS,\n JETSTREAM_CONNECTION,\n PatternRegistry,\n StreamProvider,\n ConsumerProvider,\n MessageProvider,\n EventRouter,\n RpcRouter,\n CoreRpcServer,\n ],\n useFactory: (\n options: JetstreamModuleOptions,\n connection: ConnectionProvider,\n patternRegistry: PatternRegistry,\n streamProvider: StreamProvider,\n consumerProvider: ConsumerProvider,\n messageProvider: MessageProvider,\n eventRouter: EventRouter,\n rpcRouter: RpcRouter,\n coreRpcServer: CoreRpcServer,\n ): JetstreamStrategy | null => {\n if (options.consumer === false) return null;\n\n return new JetstreamStrategy(\n options,\n connection,\n patternRegistry,\n streamProvider,\n consumerProvider,\n messageProvider,\n eventRouter,\n rpcRouter,\n coreRpcServer,\n );\n },\n },\n ];\n }\n\n /** Create async options provider from useFactory/useExisting/useClass. */\n private static createAsyncOptionsProvider(asyncOptions: JetstreamModuleAsyncOptions): Provider[] {\n if (asyncOptions.useFactory) {\n const factory = asyncOptions.useFactory;\n\n return [\n {\n provide: JETSTREAM_OPTIONS,\n useFactory: async (...args: unknown[]): Promise<JetstreamModuleOptions> => {\n const partial = await factory(...args);\n\n return { ...partial, name: asyncOptions.name } satisfies JetstreamModuleOptions;\n },\n inject: asyncOptions.inject ?? [],\n },\n ];\n }\n\n if (asyncOptions.useExisting) {\n return [\n {\n provide: JETSTREAM_OPTIONS,\n useFactory: (config: Omit<JetstreamModuleOptions, 'name'>): JetstreamModuleOptions => ({\n ...config,\n name: asyncOptions.name,\n }),\n inject: [asyncOptions.useExisting],\n },\n ];\n }\n\n // useClass — guaranteed by the discriminated union after excluding useFactory and useExisting\n const useClass = asyncOptions.useClass;\n\n return [\n { provide: useClass, useClass },\n {\n provide: JETSTREAM_OPTIONS,\n useFactory: (config: Omit<JetstreamModuleOptions, 'name'>): JetstreamModuleOptions => ({\n ...config,\n name: asyncOptions.name,\n }),\n inject: [useClass],\n },\n ];\n }\n\n // -------------------------------------------------------------------\n // Lifecycle hooks\n // -------------------------------------------------------------------\n\n /**\n * Gracefully shut down the transport on application termination.\n */\n public async onApplicationShutdown(): Promise<void> {\n if (this.shutdownManager) {\n await this.shutdownManager.shutdown(this.strategy ?? undefined);\n }\n }\n}\n","import { Logger } from '@nestjs/common';\nimport { ClientProxy, ReadPacket, WritePacket } from '@nestjs/microservices';\nimport {\n createInbox,\n Events,\n headers as natsHeaders,\n Msg,\n MsgHdrs,\n NatsConnection,\n Subscription,\n} from 'nats';\nimport { Subscription as RxSubscription } from 'rxjs';\n\nimport { ConnectionProvider } from '../connection';\nimport { EventBus } from '../hooks';\nimport { TransportEvent } from '../interfaces';\nimport type {\n Codec,\n ExtractedRecordData,\n JetstreamModuleOptions,\n TransportHeaderOptions,\n} from '../interfaces';\nimport {\n buildBroadcastSubject,\n buildSubject,\n DEFAULT_JETSTREAM_RPC_TIMEOUT,\n DEFAULT_RPC_TIMEOUT,\n internalName,\n JetstreamHeader,\n} from '../jetstream.constants';\n\nimport { JetstreamRecord } from './jetstream.record';\n\n/**\n * NestJS ClientProxy implementation for the JetStream transport.\n *\n * Supports two operational modes:\n * - **Core mode** (default): Uses `nc.request()` for RPC, `nc.publish()` for events.\n * - **JetStream mode**: Uses `js.publish()` for RPC commands + inbox for responses.\n *\n * Events always go through JetStream publish for guaranteed delivery.\n * The mode only affects RPC (request/reply) behavior.\n *\n * Clients are lightweight — they share the NATS connection from `forRoot()`.\n */\nexport class JetstreamClient extends ClientProxy {\n private readonly logger = new Logger('Jetstream:Client');\n\n /** Target service name this client sends messages to. */\n private readonly targetName: string;\n\n /** Shared inbox for JetStream-mode RPC responses. */\n private inbox: string | null = null;\n private inboxSubscription: Subscription | null = null;\n\n /** Pending JetStream-mode RPC callbacks, keyed by correlation ID. */\n private readonly pendingMessages = new Map<string, (p: WritePacket) => void>();\n\n /** Pending JetStream-mode RPC timeouts, keyed by correlation ID. */\n private readonly pendingTimeouts = new Map<string, ReturnType<typeof setTimeout>>();\n\n /** Subscription to connection status events for disconnect handling. */\n private statusSubscription: RxSubscription | null = null;\n\n public constructor(\n private readonly rootOptions: JetstreamModuleOptions,\n targetServiceName: string,\n private readonly connection: ConnectionProvider,\n private readonly codec: Codec,\n private readonly eventBus: EventBus,\n ) {\n super();\n this.targetName = targetServiceName;\n }\n\n /** Establish connection. Called automatically by NestJS on first use. */\n public async connect(): Promise<NatsConnection> {\n const nc = await this.connection.getConnection();\n\n // Setup inbox for JetStream RPC mode\n if (this.isJetStreamRpcMode() && !this.inboxSubscription) {\n this.setupInbox(nc);\n }\n\n // Subscribe to disconnect events (once)\n this.statusSubscription ??= this.connection.status$.subscribe((status) => {\n if (status.type === Events.Disconnect) {\n this.handleDisconnect();\n }\n });\n\n return nc;\n }\n\n /** Clean up resources. */\n public async close(): Promise<void> {\n this.statusSubscription?.unsubscribe();\n this.statusSubscription = null;\n this.rejectPendingRpcs(new Error('Client closed'));\n }\n\n /** Direct access to the raw NATS connection. */\n public override unwrap<T = NatsConnection>(): T {\n const nc = this.connection.unwrap;\n\n if (!nc) {\n throw new Error('Not connected — call connect() before unwrap()');\n }\n\n return nc as T;\n }\n\n /**\n * Publish a fire-and-forget event to JetStream.\n *\n * Events are published to either the workqueue stream or broadcast stream\n * depending on the subject prefix.\n */\n protected async dispatchEvent<T = unknown>(packet: ReadPacket): Promise<T> {\n const nc = await this.connect();\n const { data, hdrs } = this.extractRecordData(packet.data);\n\n // Determine if this is a broadcast event\n // Broadcast subjects start with 'broadcast:'\n const subject = this.buildEventSubject(packet.pattern);\n const msgHeaders = this.buildHeaders(hdrs, { subject });\n\n const ack = await nc.jetstream().publish(subject, this.codec.encode(data), {\n headers: msgHeaders,\n msgID: crypto.randomUUID(),\n });\n\n if (ack.duplicate) {\n this.logger.warn(`Duplicate event publish detected: ${subject} (seq: ${ack.seq})`);\n }\n\n return undefined as T;\n }\n\n /**\n * Publish an RPC command and register callback for response.\n *\n * Core mode: uses nc.request() with timeout.\n * JetStream mode: publishes to stream + waits for inbox response.\n */\n protected publish(packet: ReadPacket, callback: (p: WritePacket) => void): () => void {\n const subject = buildSubject(this.targetName, 'cmd', packet.pattern);\n const { data, hdrs, timeout } = this.extractRecordData(packet.data);\n\n const onUnhandled = (err: unknown): void => {\n this.logger.error('Unhandled publish error:', err);\n callback({ err: new Error('Internal transport error'), response: null, isDisposed: true });\n };\n\n // Track correlation ID for cleanup in JetStream mode\n let jetStreamCorrelationId: string | null = null;\n\n if (this.isCoreRpcMode()) {\n this.publishCoreRpc(subject, data, hdrs, timeout, callback).catch(onUnhandled);\n } else {\n jetStreamCorrelationId = crypto.randomUUID();\n this.publishJetStreamRpc(\n subject,\n data,\n hdrs,\n timeout,\n callback,\n jetStreamCorrelationId,\n ).catch(onUnhandled);\n }\n\n return () => {\n // Cleanup for JetStream mode pending messages\n // Core mode cleanup is handled by NATS internally\n if (jetStreamCorrelationId) {\n const timeoutId = this.pendingTimeouts.get(jetStreamCorrelationId);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n this.pendingTimeouts.delete(jetStreamCorrelationId);\n }\n\n this.pendingMessages.delete(jetStreamCorrelationId);\n }\n };\n }\n\n /** Core mode: nc.request() with timeout. */\n private async publishCoreRpc(\n subject: string,\n data: unknown,\n customHeaders: Map<string, string> | null,\n timeout: number | undefined,\n callback: (p: WritePacket) => void,\n ): Promise<void> {\n try {\n const nc = await this.connect();\n const effectiveTimeout = timeout ?? this.getRpcTimeout();\n const hdrs = this.buildHeaders(customHeaders, { subject });\n\n const response = await nc.request(subject, this.codec.encode(data), {\n timeout: effectiveTimeout,\n headers: hdrs,\n });\n\n const decoded = this.codec.decode(response.data);\n\n if (response.headers?.get(JetstreamHeader.Error)) {\n callback({ err: decoded, response: null, isDisposed: true });\n } else {\n callback({ err: null, response: decoded, isDisposed: true });\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Unknown error');\n\n this.logger.error(`Core RPC error (${subject}):`, err);\n this.eventBus.emit(TransportEvent.Error, error, 'client-rpc');\n callback({ err: error, response: null, isDisposed: true });\n }\n }\n\n /** JetStream mode: publish to stream + wait for inbox response. */\n private async publishJetStreamRpc(\n subject: string,\n data: unknown,\n customHeaders: Map<string, string> | null,\n timeout: number | undefined,\n callback: (p: WritePacket) => void,\n correlationId: string = crypto.randomUUID(),\n ): Promise<void> {\n const effectiveTimeout = timeout ?? this.getRpcTimeout();\n\n this.pendingMessages.set(correlationId, callback);\n\n const timeoutId = setTimeout(() => {\n if (!this.pendingMessages.has(correlationId)) return;\n\n this.pendingTimeouts.delete(correlationId);\n this.pendingMessages.delete(correlationId);\n this.logger.error(`JetStream RPC timeout (${effectiveTimeout}ms): ${subject}`);\n this.eventBus.emit(TransportEvent.RpcTimeout, subject, correlationId);\n callback({ err: new Error('RPC timeout'), response: null, isDisposed: true });\n }, effectiveTimeout);\n\n this.pendingTimeouts.set(correlationId, timeoutId);\n\n try {\n const nc = await this.connect();\n\n if (!this.inbox) {\n throw new Error('Inbox not initialized — JetStream RPC mode requires a connected inbox');\n }\n\n const hdrs = this.buildHeaders(customHeaders, {\n subject,\n correlationId,\n replyTo: this.inbox,\n });\n\n await nc.jetstream().publish(subject, this.codec.encode(data), {\n headers: hdrs,\n msgID: crypto.randomUUID(),\n });\n } catch (err) {\n clearTimeout(timeoutId);\n this.pendingTimeouts.delete(correlationId);\n\n if (!this.pendingMessages.has(correlationId)) return;\n\n this.pendingMessages.delete(correlationId);\n const error = err instanceof Error ? err : new Error('Unknown error');\n\n this.logger.error(`JetStream RPC publish error (${subject}):`, err);\n callback({ err: error, response: null, isDisposed: true });\n }\n }\n\n /** Fail-fast all pending JetStream RPC callbacks on connection loss. */\n private handleDisconnect(): void {\n this.rejectPendingRpcs(new Error('Connection lost'));\n\n // Reset inbox — will be recreated on next connect()\n this.inbox = null;\n }\n\n /** Reject all pending RPC callbacks, clear timeouts, and tear down inbox. */\n private rejectPendingRpcs(error: Error): void {\n for (const callback of this.pendingMessages.values()) {\n callback({ err: error, response: null, isDisposed: true });\n }\n\n for (const timeoutId of this.pendingTimeouts.values()) {\n clearTimeout(timeoutId);\n }\n\n this.pendingMessages.clear();\n this.pendingTimeouts.clear();\n this.inboxSubscription?.unsubscribe();\n this.inboxSubscription = null;\n }\n\n /** Setup shared inbox subscription for JetStream RPC responses. */\n private setupInbox(nc: NatsConnection): void {\n this.inbox = createInbox(internalName(this.rootOptions.name));\n\n this.inboxSubscription = nc.subscribe(this.inbox, {\n callback: (err, msg) => {\n if (err) {\n this.logger.error('Inbox subscription error:', err);\n return;\n }\n\n this.routeInboxReply(msg);\n },\n });\n\n this.logger.debug(`Inbox subscription: ${this.inbox}`);\n }\n\n /** Route an inbox reply to the matching pending callback. */\n private routeInboxReply(msg: Msg): void {\n const correlationId = msg.headers?.get(JetstreamHeader.CorrelationId);\n\n if (!correlationId) {\n this.logger.warn('Inbox reply without correlation-id, ignoring');\n return;\n }\n\n const callback = this.pendingMessages.get(correlationId);\n\n if (!callback) {\n this.logger.warn(`No pending handler for correlation-id: ${correlationId}`);\n return;\n }\n\n const timeoutId = this.pendingTimeouts.get(correlationId);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n this.pendingTimeouts.delete(correlationId);\n }\n\n try {\n const decoded = this.codec.decode(msg.data);\n\n if (msg.headers?.get(JetstreamHeader.Error)) {\n callback({ err: decoded, response: null, isDisposed: true });\n } else {\n callback({ err: null, response: decoded, isDisposed: true });\n }\n } catch (err) {\n callback({\n err: err instanceof Error ? err : new Error('Decode error'),\n response: null,\n isDisposed: true,\n });\n } finally {\n this.pendingMessages.delete(correlationId);\n }\n }\n\n /** Build event subject — workqueue or broadcast. */\n private buildEventSubject(pattern: string): string {\n // Convention: 'broadcast:' prefix routes to the shared broadcast stream.\n // The prefix is stripped and the pattern is published to broadcast.{pattern}.\n // Example: 'broadcast:user.created' → 'broadcast.user.created'\n if (pattern.startsWith('broadcast:')) {\n return buildBroadcastSubject(pattern.slice('broadcast:'.length));\n }\n\n return buildSubject(this.targetName, 'ev', pattern);\n }\n\n /** Build NATS headers merging custom headers with transport headers. */\n private buildHeaders(\n customHeaders: Map<string, string> | null,\n transport: TransportHeaderOptions,\n ): MsgHdrs {\n const hdrs = natsHeaders();\n\n // Set transport headers\n hdrs.set(JetstreamHeader.Subject, transport.subject);\n hdrs.set(JetstreamHeader.CallerName, internalName(this.rootOptions.name));\n\n if (transport.correlationId) {\n hdrs.set(JetstreamHeader.CorrelationId, transport.correlationId);\n }\n\n if (transport.replyTo) {\n hdrs.set(JetstreamHeader.ReplyTo, transport.replyTo);\n }\n\n // Merge user headers (reserved headers already validated by JetstreamRecordBuilder)\n if (customHeaders) {\n for (const [key, value] of customHeaders) {\n hdrs.set(key, value);\n }\n }\n\n return hdrs;\n }\n\n /** Extract data, headers, and timeout from raw packet data or JetstreamRecord. */\n private extractRecordData(rawData: unknown): ExtractedRecordData {\n if (rawData instanceof JetstreamRecord) {\n return {\n data: rawData.data,\n hdrs: rawData.headers.size > 0 ? new Map(rawData.headers) : null,\n timeout: rawData.timeout,\n };\n }\n\n return { data: rawData, hdrs: null, timeout: undefined };\n }\n\n private isCoreRpcMode(): boolean {\n return !this.rootOptions.rpc || this.rootOptions.rpc.mode === 'core';\n }\n\n private isJetStreamRpcMode(): boolean {\n return this.rootOptions.rpc?.mode === 'jetstream';\n }\n\n private getRpcTimeout(): number {\n if (!this.rootOptions.rpc) return DEFAULT_RPC_TIMEOUT;\n\n const defaultTimeout = this.isJetStreamRpcMode()\n ? DEFAULT_JETSTREAM_RPC_TIMEOUT\n : DEFAULT_RPC_TIMEOUT;\n\n return this.rootOptions.rpc.timeout ?? defaultTimeout;\n }\n}\n","import type { MsgHdrs } from 'nats';\n\nexport enum TransportEvent {\n Connect = 'connect',\n Disconnect = 'disconnect',\n Reconnect = 'reconnect',\n Error = 'error',\n RpcTimeout = 'rpcTimeout',\n MessageRouted = 'messageRouted',\n ShutdownStart = 'shutdownStart',\n ShutdownComplete = 'shutdownComplete',\n DeadLetter = 'deadLetter',\n}\n\n/**\n * Hook callbacks for transport lifecycle and operational events.\n *\n * Each hook has a default implementation that logs via NestJS Logger.\n * Providing a custom hook replaces the default for that specific event.\n * Hooks that are not overridden continue using the Logger fallback.\n *\n * @example\n * ```typescript\n * JetstreamModule.forRoot({\n * hooks: {\n * [TransportEvent.Error]: (error, context) => sentry.captureException(error),\n * [TransportEvent.RpcTimeout]: (subject) => metrics.increment('rpc.timeout'),\n * },\n * })\n * ```\n */\nexport interface TransportHooks {\n /** Fired when NATS connection is established. */\n [TransportEvent.Connect](server: string): void;\n\n /** Fired when NATS connection is lost. */\n [TransportEvent.Disconnect](): void;\n\n /** Fired when NATS connection is re-established after a disconnect. */\n [TransportEvent.Reconnect](server: string): void;\n\n /** Fired on any transport-level error. */\n [TransportEvent.Error](error: Error, context?: string): void;\n\n /** Fired when an RPC handler exceeds its timeout. */\n [TransportEvent.RpcTimeout](subject: string, correlationId: string): void;\n\n /** Fired after a message is successfully routed to its handler. */\n [TransportEvent.MessageRouted](subject: string, kind: 'rpc' | 'event'): void;\n\n /** Fired at the start of the graceful shutdown sequence. */\n [TransportEvent.ShutdownStart](): void;\n\n /** Fired after graceful shutdown completes. */\n [TransportEvent.ShutdownComplete](): void;\n\n /** Fired when a message exhausts all delivery attempts (dead letter). */\n [TransportEvent.DeadLetter](info: DeadLetterInfo): void;\n}\n\n/**\n * Context passed to the onDeadLetter callback when a message exhausts all delivery attempts.\n */\nexport interface DeadLetterInfo {\n /** The NATS subject the message was published to. */\n subject: string;\n /** Decoded message payload. */\n data: unknown;\n /** Message headers (raw NATS MsgHdrs). */\n headers: MsgHdrs | undefined;\n /** The error that caused the last handler failure. */\n error: unknown;\n /** How many times this message was delivered. */\n deliveryCount: number;\n /** The stream this message belongs to. */\n stream: string;\n /** The stream sequence number. */\n streamSequence: number;\n /** ISO timestamp of the message (derived from msg.info.timestampNanos). */\n timestamp: string;\n}\n","import {\n AckPolicy,\n DeliverPolicy,\n DiscardPolicy,\n ReplayPolicy,\n RetentionPolicy,\n StorageType,\n StoreCompression,\n} from 'nats';\nimport type { ConsumerConfig, StreamConfig } from 'nats';\n\nimport type { StreamKind, SubjectKind } from './interfaces';\n\n// ---------------------------------------------------------------------------\n// Injection Tokens\n// ---------------------------------------------------------------------------\n\n/** Token for the resolved JetstreamModuleOptions. */\nexport const JETSTREAM_OPTIONS = Symbol('JETSTREAM_OPTIONS');\n\n/** Token for the shared ConnectionProvider instance. */\nexport const JETSTREAM_CONNECTION = Symbol('JETSTREAM_CONNECTION');\n\n/** Token for the global Codec instance. */\nexport const JETSTREAM_CODEC = Symbol('JETSTREAM_CODEC');\n\n/** Token for the EventBus instance. */\nexport const JETSTREAM_EVENT_BUS = Symbol('JETSTREAM_EVENT_BUS');\n\n/**\n * Generate a unique injection token for a forFeature client.\n * This is what users inject with `@Inject('service-name')`.\n */\nexport const getClientToken = (name: string): string => name;\n\n// ---------------------------------------------------------------------------\n// Size & Time Helpers\n// ---------------------------------------------------------------------------\n\nconst KB = 1024;\nconst MB = 1024 * KB;\nconst GB = 1024 * MB;\n\n/** Convert milliseconds to nanoseconds (NATS JetStream format). */\nexport const nanos = (ms: number): number => ms * 1_000_000;\n\n// ---------------------------------------------------------------------------\n// Default Stream Configurations\n// ---------------------------------------------------------------------------\n\n/* eslint-disable @typescript-eslint/naming-convention -- NATS API uses snake_case property names */\n\n/** Base stream config shared by all stream types. */\nconst baseStreamConfig: Partial<StreamConfig> = {\n retention: RetentionPolicy.Workqueue,\n storage: StorageType.File,\n num_replicas: 1,\n discard: DiscardPolicy.Old,\n allow_direct: true,\n compression: StoreCompression.None,\n};\n\n/** Default config for workqueue event streams. */\nexport const DEFAULT_EVENT_STREAM_CONFIG: Partial<StreamConfig> = {\n ...baseStreamConfig,\n allow_rollup_hdrs: true,\n max_consumers: 100,\n max_msg_size: 10 * MB,\n max_msgs_per_subject: 5_000_000,\n max_msgs: 50_000_000,\n max_bytes: 5 * GB,\n max_age: nanos(7 * 24 * 60 * 60 * 1000), // 7 days\n duplicate_window: nanos(2 * 60 * 1000), // 2 min\n};\n\n/** Default config for RPC command streams (jetstream mode only). */\nexport const DEFAULT_COMMAND_STREAM_CONFIG: Partial<StreamConfig> = {\n ...baseStreamConfig,\n allow_rollup_hdrs: false,\n max_consumers: 50,\n max_msg_size: 5 * MB,\n max_msgs_per_subject: 100_000,\n max_msgs: 1_000_000,\n max_bytes: 100 * MB,\n max_age: nanos(3 * 60 * 1000), // 3 min\n duplicate_window: nanos(30 * 1000), // 30s\n};\n\n/** Default config for broadcast event streams. */\nexport const DEFAULT_BROADCAST_STREAM_CONFIG: Partial<StreamConfig> = {\n ...baseStreamConfig,\n retention: RetentionPolicy.Limits,\n allow_rollup_hdrs: true,\n max_consumers: 200,\n max_msg_size: 10 * MB,\n max_msgs_per_subject: 1_000_000,\n max_msgs: 10_000_000,\n max_bytes: 2 * GB,\n max_age: nanos(24 * 60 * 60 * 1000), // 1 day\n duplicate_window: nanos(2 * 60 * 1000), // 2 min\n};\n\n// ---------------------------------------------------------------------------\n// Default Consumer Configurations\n// ---------------------------------------------------------------------------\n\n/** Default config for workqueue event consumers. */\nexport const DEFAULT_EVENT_CONSUMER_CONFIG: Partial<ConsumerConfig> = {\n ack_wait: nanos(10 * 1000), // 10s\n max_deliver: 3,\n max_ack_pending: 100,\n ack_policy: AckPolicy.Explicit,\n deliver_policy: DeliverPolicy.All,\n replay_policy: ReplayPolicy.Instant,\n};\n\n/** Default config for RPC command consumers (jetstream mode only). */\nexport const DEFAULT_COMMAND_CONSUMER_CONFIG: Partial<ConsumerConfig> = {\n ack_wait: nanos(5 * 60 * 1000), // 5 min\n max_deliver: 1,\n max_ack_pending: 100,\n ack_policy: AckPolicy.Explicit,\n deliver_policy: DeliverPolicy.All,\n replay_policy: ReplayPolicy.Instant,\n};\n\n/** Default config for broadcast event consumers. */\nexport const DEFAULT_BROADCAST_CONSUMER_CONFIG: Partial<ConsumerConfig> = {\n ack_wait: nanos(10 * 1000), // 10s\n max_deliver: 3,\n max_ack_pending: 100,\n ack_policy: AckPolicy.Explicit,\n deliver_policy: DeliverPolicy.All,\n replay_policy: ReplayPolicy.Instant,\n};\n\n/* eslint-enable @typescript-eslint/naming-convention */\n\n// ---------------------------------------------------------------------------\n// Default Module Options\n// ---------------------------------------------------------------------------\n\nexport const DEFAULT_RPC_TIMEOUT = 30_000; // 30s for core mode\n\nexport const DEFAULT_JETSTREAM_RPC_TIMEOUT = 180_000; // 3 min for jetstream mode\n\nexport const DEFAULT_SHUTDOWN_TIMEOUT = 10_000; // 10s\n\n// ---------------------------------------------------------------------------\n// Reserved Headers\n// ---------------------------------------------------------------------------\n\n/** NATS headers managed by the transport. Users cannot overwrite these. */\nexport enum JetstreamHeader {\n CorrelationId = 'x-correlation-id',\n ReplyTo = 'x-reply-to',\n Subject = 'x-subject',\n CallerName = 'x-caller-name',\n RequestId = 'x-request-id',\n TraceId = 'x-trace-id',\n SpanId = 'x-span-id',\n /** Set to 'true' on error responses so the client can distinguish success from failure. */\n Error = 'x-error',\n}\n\n/** Set of header names that are reserved and cannot be set by users. */\nexport const RESERVED_HEADERS = new Set<string>([\n JetstreamHeader.CorrelationId,\n JetstreamHeader.ReplyTo,\n JetstreamHeader.Error,\n]);\n\n// ---------------------------------------------------------------------------\n// Naming Helpers\n// ---------------------------------------------------------------------------\n\n/** Internal service name with microservice suffix. */\nexport const internalName = (name: string): string => `${name}__microservice`;\n\n/** Build a fully-qualified NATS subject. */\nexport const buildSubject = (serviceName: string, kind: SubjectKind, pattern: string): string =>\n `${internalName(serviceName)}.${kind}.${pattern}`;\n\n/** Build a broadcast subject. */\nexport const buildBroadcastSubject = (pattern: string): string => `broadcast.${pattern}`;\n\n/** Stream name for a given service and kind. */\nexport const streamName = (serviceName: string, kind: StreamKind): string => {\n if (kind === 'broadcast') return 'broadcast-stream';\n return `${internalName(serviceName)}_${kind}-stream`;\n};\n\n/** Consumer name for a given service and kind. */\nexport const consumerName = (serviceName: string, kind: StreamKind): string => {\n if (kind === 'broadcast') return `${internalName(serviceName)}_broadcast-consumer`;\n return `${internalName(serviceName)}_${kind}-consumer`;\n};\n","import { RESERVED_HEADERS } from '../jetstream.constants';\n\n/**\n * Immutable message record for JetStream transport.\n *\n * Compatible with NestJS record builder pattern (like RmqRecord, NatsRecord).\n * Pass as the second argument to `client.send()` or `client.emit()`.\n *\n * @example\n * ```typescript\n * const record = new JetstreamRecordBuilder({ id: 1 })\n * .setHeader('x-tenant', 'acme')\n * .setTimeout(5000)\n * .build();\n *\n * client.send('get.user', record);\n * ```\n */\nexport class JetstreamRecord<TData = unknown> {\n public constructor(\n public readonly data: TData,\n public readonly headers: ReadonlyMap<string, string>,\n public readonly timeout?: number,\n ) {}\n}\n\n/**\n * Fluent builder for constructing JetstreamRecord instances.\n *\n * Protected headers (`correlation-id`, `reply-to`, `error`) cannot be\n * set by the user — attempting to do so throws an error at build time.\n */\nexport class JetstreamRecordBuilder<TData = unknown> {\n private data: TData | undefined;\n private readonly headers = new Map<string, string>();\n private timeout: number | undefined;\n\n public constructor(data?: TData) {\n this.data = data;\n }\n\n /** Set the message payload. */\n public setData(data: TData): this {\n this.data = data;\n return this;\n }\n\n /**\n * Set a single custom header.\n *\n * @throws Error if the header name is reserved by the transport.\n */\n public setHeader(key: string, value: string): this {\n this.validateHeaderKey(key);\n this.headers.set(key, value);\n return this;\n }\n\n /**\n * Set multiple custom headers at once.\n *\n * @throws Error if any header name is reserved by the transport.\n */\n public setHeaders(headers: Record<string, string>): this {\n for (const [key, value] of Object.entries(headers)) {\n this.setHeader(key, value);\n }\n\n return this;\n }\n\n /** Set RPC request timeout in milliseconds. */\n public setTimeout(ms: number): this {\n this.timeout = ms;\n return this;\n }\n\n /** Build the immutable JetstreamRecord. */\n public build(): JetstreamRecord<TData> {\n return new JetstreamRecord(this.data as TData, new Map(this.headers), this.timeout);\n }\n\n /** Validate that a header key is not reserved. */\n private validateHeaderKey(key: string): void {\n if (RESERVED_HEADERS.has(key)) {\n throw new Error(\n `Header \"${key}\" is reserved by the JetStream transport and cannot be set manually. ` +\n `Reserved headers: ${[...RESERVED_HEADERS].join(', ')}`,\n );\n }\n }\n}\n","import { JSONCodec as NatsJSONCodec } from 'nats';\n\nimport type { Codec } from '../interfaces';\n\n/**\n * Default JSON codec wrapping the nats.js JSONCodec.\n *\n * Serializes to/from JSON using the native NATS implementation\n * which handles `TextEncoder`/`TextDecoder` internally.\n *\n * @example\n * ```typescript\n * const codec = new JsonCodec();\n * const bytes = codec.encode({ hello: 'world' });\n * const data = codec.decode(bytes); // { hello: 'world' }\n * ```\n */\nexport class JsonCodec implements Codec {\n private readonly inner = NatsJSONCodec();\n\n public encode(data: unknown): Uint8Array {\n return this.inner.encode(data);\n }\n\n public decode(data: Uint8Array): unknown {\n return this.inner.decode(data);\n }\n}\n","import { Logger } from '@nestjs/common';\nimport {\n connect,\n ConnectionOptions,\n DebugEvents,\n Events,\n JetStreamManager,\n NatsConnection,\n NatsError,\n Status,\n} from 'nats';\nimport { defer, from, Observable, share, shareReplay, switchMap } from 'rxjs';\n\nimport { EventBus } from '../hooks';\nimport { TransportEvent } from '../interfaces';\nimport type { JetstreamModuleOptions } from '../interfaces';\nimport { internalName } from '../jetstream.constants';\n\n/**\n * Manages the lifecycle of a single NATS connection shared across the application.\n *\n * Provides both Promise-based and Observable-based access to the connection:\n * - `connect()` / `getConnection()` — async/await for one-time setup\n * - `nc$` — cached observable (shareReplay) for reactive consumers\n * - `status$` — live connection status event stream\n *\n * One instance per application, created by `JetstreamModule.forRoot()`.\n */\nexport class ConnectionProvider {\n /** Cached observable that replays the established connection to new subscribers. */\n public readonly nc$: Observable<NatsConnection>;\n\n /** Live stream of connection status events (no replay). */\n public readonly status$: Observable<Status>;\n\n private readonly logger = new Logger('Jetstream:Connection');\n\n private connection: NatsConnection | null = null;\n private connectionPromise: Promise<NatsConnection> | null = null;\n private jsmInstance: JetStreamManager | null = null;\n\n public constructor(\n private readonly options: JetstreamModuleOptions,\n private readonly eventBus: EventBus,\n ) {\n // Lazy observable — connects on first subscription, caches for all future subscribers\n this.nc$ = defer(() => this.getConnection()).pipe(\n shareReplay({ bufferSize: 1, refCount: false }),\n );\n\n this.status$ = this.nc$.pipe(\n switchMap((nc) => from(nc.status())),\n share(),\n );\n }\n\n /**\n * Establish NATS connection. Idempotent — returns cached connection on subsequent calls.\n *\n * @throws Error if connection is refused (fail fast).\n */\n public async getConnection(): Promise<NatsConnection> {\n if (this.connection && !this.connection.isClosed()) {\n return this.connection;\n }\n\n if (this.connectionPromise) {\n return this.connectionPromise;\n }\n\n this.connectionPromise = this.establish().catch((err) => {\n this.connectionPromise = null;\n throw err;\n });\n\n return this.connectionPromise;\n }\n\n /**\n * Get JetStream manager. Cached after first call.\n */\n public async getJetStreamManager(): Promise<JetStreamManager> {\n if (this.jsmInstance) return this.jsmInstance;\n\n const nc = await this.getConnection();\n\n this.jsmInstance = await nc.jetstreamManager();\n this.logger.log('JetStream manager initialized');\n return this.jsmInstance;\n }\n\n /** Direct access to the raw NATS connection (assumes already connected). */\n public get unwrap(): NatsConnection | null {\n return this.connection;\n }\n\n /**\n * Gracefully shut down the connection.\n *\n * Sequence: drain → wait for close. Falls back to force-close on error.\n */\n public async shutdown(): Promise<void> {\n if (!this.connection || this.connection.isClosed()) return;\n\n try {\n await this.connection.drain();\n await this.connection.closed();\n } catch {\n try {\n await this.connection.close();\n } catch {\n // Best-effort — connection may already be gone\n }\n } finally {\n this.connection = null;\n this.connectionPromise = null;\n this.jsmInstance = null;\n }\n }\n\n /** Internal: establish the physical connection with reconnect monitoring. */\n private async establish(): Promise<NatsConnection> {\n const name = internalName(this.options.name);\n\n try {\n const nc = await connect({\n ...this.options.connectionOptions,\n servers: this.options.servers,\n name,\n } as ConnectionOptions);\n\n this.connection = nc;\n this.logger.log(`NATS connection established: ${nc.getServer()}`);\n this.eventBus.emit(TransportEvent.Connect, nc.getServer());\n\n this.monitorStatus(nc);\n\n return nc;\n } catch (err) {\n if (err instanceof NatsError && err.code === 'CONNECTION_REFUSED') {\n throw new Error(`NATS connection refused: ${this.options.servers.join(', ')}`);\n }\n\n throw err;\n }\n }\n\n /** Subscribe to connection status events and emit hooks. */\n private monitorStatus(nc: NatsConnection): void {\n (async (): Promise<void> => {\n for await (const status of nc.status()) {\n switch (status.type) {\n case Events.Disconnect:\n this.eventBus.emit(TransportEvent.Disconnect);\n break;\n case Events.Reconnect:\n this.jsmInstance = null; // Invalidate cached JSM\n this.eventBus.emit(TransportEvent.Reconnect, nc.getServer());\n break;\n case Events.Error:\n this.eventBus.emit(TransportEvent.Error, new Error(String(status.data)), 'connection');\n break;\n case Events.Update:\n case Events.LDM:\n case DebugEvents.Reconnecting:\n case DebugEvents.PingTimer:\n case DebugEvents.StaleConnection:\n case DebugEvents.ClientInitiatedReconnect:\n break;\n }\n }\n })().catch((err) => {\n this.logger.error('Status monitor error', err);\n });\n }\n}\n","import { Logger } from '@nestjs/common';\n\nimport { TransportEvent } from '../interfaces';\nimport type { TransportHooks } from '../interfaces';\n\n/**\n * Central event bus for transport lifecycle notifications.\n *\n * Dispatches events to user-provided hooks or falls back to\n * the NestJS Logger for each event type independently.\n *\n * @example\n * ```typescript\n * const bus = new EventBus(logger, {\n * [TransportEvent.Error]: (err) => sentry.captureException(err),\n * });\n *\n * bus.emit(TransportEvent.Error, new Error('timeout'), 'rpc-router');\n * // → calls sentry, not logger\n *\n * bus.emit(TransportEvent.Connect, 'nats://localhost:4222');\n * // → calls logger.log (no custom hook for connect)\n * ```\n */\nexport class EventBus {\n private readonly hooks: Partial<TransportHooks>;\n private readonly logger: Logger;\n\n public constructor(logger: Logger, hooks?: Partial<TransportHooks>) {\n this.logger = logger;\n this.hooks = hooks ?? {};\n }\n\n /** Emit a lifecycle event. Dispatches to custom hook or Logger fallback. */\n public emit<K extends keyof TransportHooks>(\n event: K,\n ...args: Parameters<TransportHooks[K]>\n ): void {\n const hook = this.hooks[event];\n\n if (hook) {\n try {\n (hook as (...a: unknown[]) => void)(...args);\n } catch (err) {\n this.logger.error(\n `Hook \"${event}\" threw an error: ${err instanceof Error ? err.message : err}`,\n );\n }\n\n return;\n }\n\n this.defaultHandler(event, args);\n }\n\n /** Default Logger-based handlers for each event type. */\n private defaultHandler(event: keyof TransportHooks, args: unknown[]): void {\n switch (event) {\n case TransportEvent.Connect:\n this.logger.log(`Connected to NATS: ${args[0]}`);\n break;\n case TransportEvent.Disconnect:\n this.logger.warn('NATS connection lost');\n break;\n case TransportEvent.Reconnect:\n this.logger.log(`Reconnected to NATS: ${args[0]}`);\n break;\n case TransportEvent.Error:\n this.logger.error(`Transport error: ${args[0]}`, args[1] ?? '');\n break;\n case TransportEvent.RpcTimeout:\n this.logger.warn(`RPC timeout: ${args[0]} (cid: ${args[1]})`);\n break;\n case TransportEvent.MessageRouted:\n this.logger.debug(`Message routed: ${args[0]} [${args[1]}]`);\n break;\n case TransportEvent.ShutdownStart:\n this.logger.log('Graceful shutdown initiated');\n break;\n case TransportEvent.ShutdownComplete:\n this.logger.log('Graceful shutdown complete');\n break;\n\n case TransportEvent.DeadLetter: {\n const info = args[0] as { subject?: string } | undefined;\n\n this.logger.warn(`Dead letter: ${info?.subject ?? 'unknown'}`);\n break;\n }\n }\n }\n}\n","import { Injectable, Logger } from '@nestjs/common';\n\nimport { ConnectionProvider } from '../connection';\n\n/**\n * Health status returned by `check()`.\n */\nexport interface JetstreamHealthStatus {\n connected: boolean;\n server: string | null;\n /** Round-trip latency in ms (null if disconnected). */\n latency: number | null;\n}\n\n/**\n * Health indicator result compatible with @nestjs/terminus.\n *\n * Follows the Terminus convention: returns status object on success,\n * throws on failure. Works with Terminus out of the box — no wrapper needed:\n *\n * @example\n * ```typescript\n * // With Terminus\n * this.health.check([() => this.jetstream.isHealthy()])\n *\n * // Standalone\n * const status = await this.jetstream.check();\n * ```\n */\n@Injectable()\nexport class JetstreamHealthIndicator {\n private readonly logger = new Logger('Jetstream:Health');\n\n public constructor(private readonly connection: ConnectionProvider) {}\n\n /**\n * Plain health status check.\n *\n * Returns the current connection status without throwing.\n * Use this for custom health endpoints or monitoring integrations.\n */\n public async check(): Promise<JetstreamHealthStatus> {\n const nc = this.connection.unwrap;\n\n if (!nc || nc.isClosed()) {\n return { connected: false, server: null, latency: null };\n }\n\n try {\n const start = performance.now();\n\n await nc.rtt();\n\n const latency = Math.round(performance.now() - start);\n\n return { connected: true, server: nc.getServer(), latency };\n } catch (err) {\n this.logger.warn(`Health check failed: ${err instanceof Error ? err.message : err}`);\n return { connected: false, server: nc.getServer(), latency: null };\n }\n }\n\n /**\n * Terminus-compatible health check.\n *\n * Returns `{ [key]: { status: 'up', ... } }` on success.\n * Throws an error with `{ [key]: { status: 'down', ... } }` on failure.\n *\n * @param key Health indicator key (default: 'jetstream')\n */\n public async isHealthy(key = 'jetstream'): Promise<Record<string, Record<string, unknown>>> {\n const status = await this.check();\n\n const details: Record<string, unknown> = {\n status: status.connected ? 'up' : 'down',\n server: status.server,\n latency: status.latency,\n };\n\n if (!status.connected) {\n throw Object.assign(new Error('Jetstream health check failed'), {\n [key]: details,\n });\n }\n\n return { [key]: details };\n }\n}\n","import { CustomTransportStrategy, Server } from '@nestjs/microservices';\n\nimport { ConnectionProvider } from '../connection';\nimport type { JetstreamModuleOptions, StreamKind } from '../interfaces';\n\nimport { CoreRpcServer } from './core-rpc.server';\nimport { ConsumerProvider, MessageProvider, StreamProvider } from './infrastructure';\nimport { EventRouter, PatternRegistry, RpcRouter } from './routing';\n\n/**\n * NestJS custom transport strategy for NATS JetStream.\n *\n * Coordinates all server-side providers:\n * 1. Registers handlers from NestJS into PatternRegistry\n * 2. Creates required streams and consumers\n * 3. Starts message consumption and routing\n * 4. Handles Core or JetStream RPC based on configuration\n *\n * All dependencies are injected via the NestJS DI container.\n */\nexport class JetstreamStrategy extends Server implements CustomTransportStrategy {\n public readonly transportId = Symbol('jetstream-transport');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n private readonly listeners = new Map<string, Function[]>();\n private started = false;\n\n public constructor(\n private readonly options: JetstreamModuleOptions,\n private readonly connection: ConnectionProvider,\n private readonly patternRegistry: PatternRegistry,\n private readonly streamProvider: StreamProvider,\n private readonly consumerProvider: ConsumerProvider,\n private readonly messageProvider: MessageProvider,\n private readonly eventRouter: EventRouter,\n private readonly rpcRouter: RpcRouter,\n private readonly coreRpcServer: CoreRpcServer,\n ) {\n super();\n }\n\n /**\n * Start the transport: register handlers, create infrastructure, begin consumption.\n *\n * Called by NestJS when `connectMicroservice()` is used, or internally by the module.\n */\n public async listen(callback: () => void): Promise<void> {\n if (this.started) {\n this.logger.warn('listen() called more than once — ignoring');\n\n return;\n }\n\n this.started = true;\n\n // 1. Register all NestJS handlers\n this.patternRegistry.registerHandlers(this.getHandlers());\n\n // 2. Determine which stream kinds are needed\n const streamKinds = this.resolveStreamKinds();\n\n if (streamKinds.length > 0) {\n // 3. Ensure streams exist\n await this.streamProvider.ensureStreams(streamKinds);\n\n // 4. Ensure consumers exist\n const consumers = await this.consumerProvider.ensureConsumers(streamKinds);\n\n // 5. Start message consumption\n this.messageProvider.start(consumers);\n\n // 6. Start event router if needed\n if (this.patternRegistry.hasEventHandlers() || this.patternRegistry.hasBroadcastHandlers()) {\n this.eventRouter.start();\n }\n\n // 7. Start RPC router if JetStream mode\n if (this.isJetStreamRpcMode() && this.patternRegistry.hasRpcHandlers()) {\n this.rpcRouter.start();\n }\n }\n\n // 8. Start Core RPC server if core mode\n if (this.isCoreRpcMode() && this.patternRegistry.hasRpcHandlers()) {\n await this.coreRpcServer.start();\n }\n\n callback();\n }\n\n /** Gracefully stop the transport. */\n public close(): void {\n this.eventRouter.destroy();\n this.rpcRouter.destroy();\n this.coreRpcServer.stop();\n this.messageProvider.destroy();\n this.started = false;\n }\n\n /**\n * Register event listener (required by Server base class).\n *\n * Stores callbacks for client use. Primary lifecycle events\n * are routed through EventBus.\n */\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n public on(event: string, callback: Function): void {\n const existing = this.listeners.get(event) ?? [];\n\n existing.push(callback);\n this.listeners.set(event, existing);\n }\n\n /** Unwrap the underlying NATS connection. */\n public unwrap<T>(): T {\n const nc = this.connection.unwrap;\n\n if (!nc) {\n throw new Error('Not connected — transport has not started');\n }\n\n return nc as T;\n }\n\n /** Access the pattern registry (for module-level introspection). */\n public getPatternRegistry(): PatternRegistry {\n return this.patternRegistry;\n }\n\n /** Determine which JetStream stream kinds are needed. */\n private resolveStreamKinds(): StreamKind[] {\n const kinds: StreamKind[] = [];\n\n if (this.patternRegistry.hasEventHandlers()) {\n kinds.push('ev');\n }\n\n if (this.isJetStreamRpcMode() && this.patternRegistry.hasRpcHandlers()) {\n kinds.push('cmd');\n }\n\n if (this.patternRegistry.hasBroadcastHandlers()) {\n kinds.push('broadcast');\n }\n\n return kinds;\n }\n\n private isCoreRpcMode(): boolean {\n return !this.options.rpc || this.options.rpc.mode === 'core';\n }\n\n private isJetStreamRpcMode(): boolean {\n return this.options.rpc?.mode === 'jetstream';\n }\n}\n","import { Logger } from '@nestjs/common';\nimport { headers as natsHeaders, Msg, Subscription } from 'nats';\n\nimport { ConnectionProvider } from '../connection';\nimport { RpcContext } from '../context';\nimport { EventBus } from '../hooks';\nimport { TransportEvent } from '../interfaces';\nimport type { Codec, JetstreamModuleOptions } from '../interfaces';\nimport { internalName, JetstreamHeader } from '../jetstream.constants';\nimport { serializeError, unwrapResult } from '../utils';\n\nimport { PatternRegistry } from './routing/pattern-registry';\n\n/**\n * Handles RPC via NATS Core request/reply pattern.\n *\n * Subscribes to `{service}.cmd.>` with a queue group for load balancing.\n * Each request is processed and replied to directly via `msg.respond()`.\n *\n * This is the default RPC mode — lowest latency, no persistence overhead.\n */\nexport class CoreRpcServer {\n private readonly logger = new Logger('Jetstream:CoreRpc');\n private subscription: Subscription | null = null;\n\n public constructor(\n private readonly options: JetstreamModuleOptions,\n private readonly connection: ConnectionProvider,\n private readonly patternRegistry: PatternRegistry,\n private readonly codec: Codec,\n private readonly eventBus: EventBus,\n ) {}\n\n /** Start listening for RPC requests on the command subject. */\n public async start(): Promise<void> {\n const nc = await this.connection.getConnection();\n const serviceName = internalName(this.options.name);\n const subject = `${serviceName}.cmd.>`;\n const queue = `${serviceName}_cmd_queue`;\n\n this.subscription = nc.subscribe(subject, {\n queue,\n callback: (err, msg) => {\n if (err) {\n this.logger.error('Core RPC subscription error:', err);\n return;\n }\n\n this.handleRequest(msg).catch((err) => {\n this.logger.error('Unhandled request error:', err);\n });\n },\n });\n\n this.logger.log(`Core RPC listening: ${subject} (queue: ${queue})`);\n }\n\n /** Stop listening and clean up the subscription. */\n public stop(): void {\n if (this.subscription) {\n this.subscription.unsubscribe();\n this.subscription = null;\n }\n }\n\n /** Handle an incoming Core NATS request. */\n private async handleRequest(msg: Msg): Promise<void> {\n const handler = this.patternRegistry.getHandler(msg.subject);\n\n if (!handler) {\n this.logger.warn(`No handler for Core RPC: ${msg.subject}`);\n return;\n }\n\n this.eventBus.emit(TransportEvent.MessageRouted, msg.subject, 'rpc');\n\n let data: unknown;\n\n try {\n data = this.codec.decode(msg.data);\n } catch (err) {\n this.logger.error(`Decode error for Core RPC ${msg.subject}:`, err);\n this.respondWithError(msg, err);\n return;\n }\n\n const ctx = new RpcContext([msg]);\n\n try {\n const result = await unwrapResult(handler(data, ctx));\n\n msg.respond(this.codec.encode(result));\n } catch (err) {\n this.logger.error(`Handler error for Core RPC ${msg.subject}:`, err);\n this.respondWithError(msg, err);\n }\n }\n\n /** Send an error response back to the caller with x-error header. */\n private respondWithError(msg: Msg, error: unknown): void {\n try {\n const hdrs = natsHeaders();\n\n hdrs.set(JetstreamHeader.Error, 'true');\n msg.respond(this.codec.encode(serializeError(error)), { headers: hdrs });\n } catch {\n this.logger.error('Failed to encode error response');\n }\n }\n}\n","import { BaseRpcContext } from '@nestjs/microservices';\nimport { JsMsg, MsgHdrs, Msg } from 'nats';\n\ntype NatsMessage = JsMsg | Msg;\n\n/**\n * Execution context for RPC and event handlers.\n *\n * Provides convenient accessors for the NATS message, subject,\n * and headers without needing to interact with the raw message directly.\n *\n * @example\n * ```typescript\n * @MessagePattern('get.user')\n * getUser(data: GetUserDto, @Ctx() ctx: RpcContext) {\n * const traceId = ctx.getHeader('x-trace-id');\n * const subject = ctx.getSubject();\n * return this.userService.findOne(data.id);\n * }\n * ```\n */\nexport class RpcContext extends BaseRpcContext<[NatsMessage]> {\n /** Get the underlying NATS message (JsMsg for JetStream, Msg for Core). */\n public getMessage(): NatsMessage {\n return this.args[0];\n }\n\n /** Get the NATS subject this message was published to. */\n public getSubject(): string {\n return this.args[0].subject;\n }\n\n /** Get all NATS message headers, or undefined if none are present. */\n public getHeaders(): MsgHdrs | undefined {\n return this.args[0].headers;\n }\n\n /** Get a single header value by key. Returns undefined if the header or headers object is missing. */\n public getHeader(key: string): string | undefined {\n return this.args[0].headers?.get(key);\n }\n\n /** Type guard: narrows getMessage() return type to JsMsg when true. */\n public isJetStream(): this is RpcContext & { getMessage(): JsMsg } {\n return 'ack' in this.args[0];\n }\n}\n","import { RpcException } from '@nestjs/microservices';\n\n/**\n * Serialize an error for transport over NATS.\n *\n * Handles three cases:\n * 1. RpcException — unwraps via getError() to preserve the full payload\n * 2. Generic Error — extracts { message } to avoid \"[object Object]\"\n * 3. Plain object — passed through as-is (already unwrapped by NestJS filters)\n */\nexport const serializeError = (err: unknown): unknown => {\n if (err instanceof RpcException) return err.getError();\n if (err instanceof Error) return { message: err.message };\n\n return err;\n};\n","import { isObservable, Observable } from 'rxjs';\n\n/**\n * Unwrap a handler result that may be a Promise, Observable, or nested combination.\n *\n * NestJS-wrapped handlers may return Promise<Observable> (e.g. when exception\n * filters convert errors to throwError() Observables). This function handles:\n *\n * - Observable → subscribe immediately (no await — preserves sync emissions)\n * - Promise<Observable> → await Promise, then subscribe\n * - Promise<value> → await\n * - Plain value → return as-is\n *\n * Used by both CoreRpcServer and RpcRouter to normalize handler output.\n */\nexport const unwrapResult = async (result: unknown): Promise<unknown> => {\n // Direct Observable — subscribe immediately (no microtask yield)\n if (isObservable(result)) {\n return subscribeToFirst(result as Observable<unknown>);\n }\n\n // Await Promise, then check if it resolved to an Observable\n // (NestJS-wrapped handlers return Promise<Observable> when exception filters fire)\n const resolved = await result;\n\n if (isObservable(resolved)) {\n return subscribeToFirst(resolved as Observable<unknown>);\n }\n\n return resolved;\n};\n\n/** Subscribe to an Observable and resolve with its first emitted value. */\nconst subscribeToFirst = (obs: Observable<unknown>): Promise<unknown> =>\n new Promise((resolve, reject) => {\n let done = false;\n\n obs.subscribe({\n next: (val: unknown) => {\n if (!done) {\n done = true;\n resolve(val);\n }\n },\n error: reject,\n complete: () => {\n if (!done) resolve(undefined);\n },\n });\n });\n","import { Logger } from '@nestjs/common';\nimport { NatsError, StreamConfig, StreamInfo } from 'nats';\n\nimport { ConnectionProvider } from '../../connection';\nimport type { JetstreamModuleOptions, StreamKind } from '../../interfaces';\nimport {\n DEFAULT_BROADCAST_STREAM_CONFIG,\n DEFAULT_COMMAND_STREAM_CONFIG,\n DEFAULT_EVENT_STREAM_CONFIG,\n internalName,\n streamName,\n} from '../../jetstream.constants';\n\n/** JetStream API error code for missing streams. */\nconst STREAM_NOT_FOUND = 10059;\n\n/**\n * Manages JetStream stream lifecycle: creation, updates, and idempotent ensures.\n *\n * Creates up to three stream types depending on configuration:\n * - **Event stream** — workqueue events (always, when consumer enabled)\n * - **Command stream** — RPC commands (only in jetstream RPC mode)\n * - **Broadcast stream** — fan-out events (only if broadcast handlers exist)\n *\n * All operations are idempotent: safe to call on every startup and reconnection.\n */\nexport class StreamProvider {\n private readonly logger = new Logger('Jetstream:Stream');\n\n public constructor(\n private readonly options: JetstreamModuleOptions,\n private readonly connection: ConnectionProvider,\n ) {}\n\n /**\n * Ensure all required streams exist with correct configuration.\n *\n * @param kinds Which stream kinds to create. Determined by the module based\n * on RPC mode and registered handler patterns.\n */\n public async ensureStreams(kinds: StreamKind[]): Promise<void> {\n const jsm = await this.connection.getJetStreamManager();\n\n await Promise.all(kinds.map((kind) => this.ensureStream(jsm, kind)));\n }\n\n /** Get the stream name for a given kind. */\n public getStreamName(kind: StreamKind): string {\n return streamName(this.options.name, kind);\n }\n\n /** Get the subjects pattern for a given kind. */\n public getSubjects(kind: StreamKind): string[] {\n const name = internalName(this.options.name);\n\n switch (kind) {\n case 'ev':\n return [`${name}.ev.>`];\n case 'cmd':\n return [`${name}.cmd.>`];\n case 'broadcast':\n return ['broadcast.>'];\n }\n }\n\n /** Ensure a single stream exists, creating or updating as needed. */\n private async ensureStream(\n jsm: Awaited<ReturnType<ConnectionProvider['getJetStreamManager']>>,\n kind: StreamKind,\n ): Promise<StreamInfo> {\n const config = this.buildConfig(kind);\n\n this.logger.log(`Ensuring stream: ${config.name}`);\n\n try {\n // Try to get existing stream info\n await jsm.streams.info(config.name);\n // Stream exists — update config\n this.logger.debug(`Stream exists, updating: ${config.name}`);\n return await jsm.streams.update(config.name, config);\n } catch (err) {\n if (err instanceof NatsError && err.api_error?.err_code === STREAM_NOT_FOUND) {\n this.logger.log(`Creating stream: ${config.name}`);\n return await jsm.streams.add(config as StreamConfig);\n }\n\n throw err;\n }\n }\n\n /** Build the full stream config by merging defaults with user overrides. */\n private buildConfig(\n kind: StreamKind,\n ): Partial<StreamConfig> & { name: string; subjects: string[] } {\n const name = this.getStreamName(kind);\n const subjects = this.getSubjects(kind);\n const description = `JetStream ${kind} stream for ${this.options.name}`;\n\n const defaults = this.getDefaults(kind);\n const overrides = this.getOverrides(kind);\n\n return {\n ...defaults,\n ...overrides,\n name,\n subjects,\n description,\n };\n }\n\n /** Get default config for a stream kind. */\n private getDefaults(kind: StreamKind): Partial<StreamConfig> {\n switch (kind) {\n case 'ev':\n return DEFAULT_EVENT_STREAM_CONFIG;\n case 'cmd':\n return DEFAULT_COMMAND_STREAM_CONFIG;\n case 'broadcast':\n return DEFAULT_BROADCAST_STREAM_CONFIG;\n }\n }\n\n /** Get user-provided overrides for a stream kind. */\n private getOverrides(kind: StreamKind): Partial<StreamConfig> {\n switch (kind) {\n case 'ev':\n return this.options.events?.stream ?? {};\n case 'cmd':\n return this.options.rpc?.mode === 'jetstream' ? (this.options.rpc.stream ?? {}) : {};\n case 'broadcast':\n return this.options.broadcast?.stream ?? {};\n }\n }\n}\n","import { Logger } from '@nestjs/common';\nimport { ConsumerConfig, ConsumerInfo, NatsError } from 'nats';\n\nimport { ConnectionProvider } from '../../connection';\nimport type { JetstreamModuleOptions, StreamKind } from '../../interfaces';\nimport {\n consumerName,\n DEFAULT_BROADCAST_CONSUMER_CONFIG,\n DEFAULT_COMMAND_CONSUMER_CONFIG,\n DEFAULT_EVENT_CONSUMER_CONFIG,\n internalName,\n} from '../../jetstream.constants';\nimport { PatternRegistry } from '../routing';\n\nimport { StreamProvider } from './stream.provider';\n\n/** JetStream API error code for missing consumers. */\nconst CONSUMER_NOT_FOUND = 10014;\n\n/**\n * Manages JetStream consumer lifecycle: creation and idempotent ensures.\n *\n * Creates durable pull-based consumers that survive restarts.\n * Consumer configuration is merged from defaults and user overrides.\n */\nexport class ConsumerProvider {\n private readonly logger = new Logger('Jetstream:Consumer');\n\n public constructor(\n private readonly options: JetstreamModuleOptions,\n private readonly connection: ConnectionProvider,\n private readonly streamProvider: StreamProvider,\n private readonly patternRegistry: PatternRegistry,\n ) {}\n\n /**\n * Ensure consumers exist for the specified kinds.\n *\n * @returns Map of kind -> ConsumerInfo for downstream use.\n */\n public async ensureConsumers(kinds: StreamKind[]): Promise<Map<StreamKind, ConsumerInfo>> {\n const jsm = await this.connection.getJetStreamManager();\n const results = new Map<StreamKind, ConsumerInfo>();\n\n await Promise.all(\n kinds.map(async (kind) => {\n const info = await this.ensureConsumer(jsm, kind);\n\n results.set(kind, info);\n }),\n );\n\n return results;\n }\n\n /** Get the consumer name for a given kind. */\n public getConsumerName(kind: StreamKind): string {\n return consumerName(this.options.name, kind);\n }\n\n /** Ensure a single consumer exists, creating if needed. */\n private async ensureConsumer(\n jsm: Awaited<ReturnType<ConnectionProvider['getJetStreamManager']>>,\n kind: StreamKind,\n ): Promise<ConsumerInfo> {\n const stream = this.streamProvider.getStreamName(kind);\n const config = this.buildConfig(kind);\n const name = config.durable_name;\n\n this.logger.log(`Ensuring consumer: ${name} on stream: ${stream}`);\n\n try {\n const info = await jsm.consumers.info(stream, name);\n\n this.logger.debug(`Consumer exists: ${name}`);\n return info;\n } catch (err) {\n if (err instanceof NatsError && err.api_error?.err_code === CONSUMER_NOT_FOUND) {\n this.logger.log(`Creating consumer: ${name}`);\n return await jsm.consumers.add(stream, config);\n }\n\n throw err;\n }\n }\n\n /** Build consumer config by merging defaults with user overrides. */\n // eslint-disable-next-line @typescript-eslint/naming-convention -- NATS API uses snake_case\n private buildConfig(kind: StreamKind): Partial<ConsumerConfig> & { durable_name: string } {\n const name = this.getConsumerName(kind);\n const serviceName = internalName(this.options.name);\n\n const defaults = this.getDefaults(kind);\n const overrides = this.getOverrides(kind);\n\n /* eslint-disable @typescript-eslint/naming-convention -- NATS API uses snake_case */\n if (kind === 'broadcast') {\n // Use specific broadcast patterns from the registry instead of a wildcard\n const broadcastPatterns = this.patternRegistry.getBroadcastPatterns();\n\n if (broadcastPatterns.length === 1) {\n return {\n ...defaults,\n ...overrides,\n name,\n durable_name: name,\n filter_subject: broadcastPatterns[0],\n };\n }\n\n return {\n ...defaults,\n ...overrides,\n name,\n durable_name: name,\n filter_subjects: broadcastPatterns,\n };\n }\n\n // Build filter_subject based on kind\n const filter_subject = kind === 'ev' ? `${serviceName}.ev.>` : `${serviceName}.cmd.>`;\n\n return {\n ...defaults,\n ...overrides,\n name,\n durable_name: name,\n filter_subject,\n };\n /* eslint-enable @typescript-eslint/naming-convention */\n }\n\n /** Get default config for a consumer kind. */\n private getDefaults(kind: StreamKind): Partial<ConsumerConfig> {\n switch (kind) {\n case 'ev':\n return DEFAULT_EVENT_CONSUMER_CONFIG;\n case 'cmd':\n return DEFAULT_COMMAND_CONSUMER_CONFIG;\n case 'broadcast':\n return DEFAULT_BROADCAST_CONSUMER_CONFIG;\n }\n }\n\n /** Get user-provided overrides for a consumer kind. */\n private getOverrides(kind: StreamKind): Partial<ConsumerConfig> {\n switch (kind) {\n case 'ev':\n return this.options.events?.consumer ?? {};\n case 'cmd':\n return this.options.rpc?.mode === 'jetstream' ? (this.options.rpc.consumer ?? {}) : {};\n case 'broadcast':\n return this.options.broadcast?.consumer ?? {};\n }\n }\n}\n","import { Logger } from '@nestjs/common';\nimport { Consumer, ConsumerInfo, ConsumerMessages, JsMsg } from 'nats';\nimport {\n catchError,\n defer,\n EMPTY,\n merge,\n Observable,\n repeat,\n Subject,\n takeUntil,\n tap,\n timer,\n} from 'rxjs';\n\nimport { ConnectionProvider } from '../../connection';\nimport { EventBus } from '../../hooks';\nimport type { StreamKind } from '../../interfaces';\nimport { TransportEvent } from '../../interfaces';\n\n/**\n * Manages pull-based message consumption from JetStream consumers.\n *\n * Uses `defer()` + `repeat()` pattern for self-healing: when the async\n * iterator completes (e.g., NATS restart), the consumer automatically\n * re-establishes after a short delay.\n *\n * Emits messages to kind-specific RxJS subjects for downstream routing.\n */\nexport class MessageProvider {\n private readonly logger = new Logger('Jetstream:Message');\n private readonly destroy$ = new Subject<void>();\n private readonly activeIterators = new Set<ConsumerMessages>();\n\n private readonly eventMessages$ = new Subject<JsMsg>();\n private readonly commandMessages$ = new Subject<JsMsg>();\n private readonly broadcastMessages$ = new Subject<JsMsg>();\n\n public constructor(\n private readonly connection: ConnectionProvider,\n private readonly eventBus: EventBus,\n ) {}\n\n /** Observable stream of workqueue event messages. */\n public get events$(): Observable<JsMsg> {\n return this.eventMessages$.asObservable();\n }\n\n /** Observable stream of RPC command messages (jetstream mode). */\n public get commands$(): Observable<JsMsg> {\n return this.commandMessages$.asObservable();\n }\n\n /** Observable stream of broadcast event messages. */\n public get broadcasts$(): Observable<JsMsg> {\n return this.broadcastMessages$.asObservable();\n }\n\n /**\n * Start consuming messages from the given consumer infos.\n *\n * Each consumer gets an independent self-healing flow.\n * Call `destroy()` to stop all consumers.\n */\n public start(consumers: Map<StreamKind, ConsumerInfo>): void {\n const flows: Observable<void>[] = [];\n\n for (const [kind, info] of consumers) {\n flows.push(this.createFlow(kind, info));\n }\n\n if (flows.length > 0) {\n merge(...flows)\n .pipe(takeUntil(this.destroy$))\n .subscribe();\n }\n }\n\n /** Stop all consumer flows and complete all subjects. */\n public destroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n\n for (const messages of this.activeIterators) {\n messages.stop();\n }\n\n this.activeIterators.clear();\n\n this.eventMessages$.complete();\n this.commandMessages$.complete();\n this.broadcastMessages$.complete();\n }\n\n /** Create a self-healing consumer flow for a specific kind. */\n private createFlow(kind: StreamKind, info: ConsumerInfo): Observable<void> {\n const target$ = this.getTargetSubject(kind);\n let consecutiveFailures = 0;\n\n return defer(() => this.consumeOnce(info, target$)).pipe(\n tap(() => {\n consecutiveFailures = 0;\n }),\n catchError((err) => {\n consecutiveFailures++;\n this.logger.error(`Consumer ${info.name} error, will restart:`, err);\n this.eventBus.emit(\n TransportEvent.Error,\n err instanceof Error ? err : new Error(String(err)),\n 'message-provider',\n );\n return EMPTY;\n }),\n repeat({\n delay: () => {\n const delay = Math.min(100 * Math.pow(2, consecutiveFailures), 30_000);\n\n this.logger.warn(`Consumer ${info.name} stream ended, restarting in ${delay}ms...`);\n this.eventBus.emit(\n TransportEvent.Error,\n new Error(`Consumer ${info.name} stream ended`),\n 'message-provider',\n );\n return timer(delay);\n },\n }),\n takeUntil(this.destroy$),\n );\n }\n\n /** Single iteration: get consumer -> pull messages -> emit to subject. */\n private async consumeOnce(info: ConsumerInfo, target$: Subject<JsMsg>): Promise<void> {\n const js = (await this.connection.getConnection()).jetstream();\n const consumer: Consumer = await js.consumers.get(info.stream_name, info.name);\n const messages = await consumer.consume();\n\n this.activeIterators.add(messages);\n\n try {\n for await (const msg of messages) {\n target$.next(msg);\n }\n } finally {\n this.activeIterators.delete(messages);\n }\n }\n\n /** Get the target subject for a consumer kind. */\n private getTargetSubject(kind: StreamKind): Subject<JsMsg> {\n switch (kind) {\n case 'ev':\n return this.eventMessages$;\n case 'cmd':\n return this.commandMessages$;\n case 'broadcast':\n return this.broadcastMessages$;\n }\n }\n}\n","import { Logger } from '@nestjs/common';\nimport { MessageHandler } from '@nestjs/microservices';\n\nimport type { JetstreamModuleOptions, PatternsByKind, RegisteredHandler } from '../../interfaces';\nimport { buildBroadcastSubject, buildSubject, internalName } from '../../jetstream.constants';\n\n/**\n * Registry mapping NATS subjects to NestJS message handlers.\n *\n * Handles subject normalization and categorization:\n * - Detects broadcast handlers via `extras.broadcast` metadata\n * - Normalizes full NATS subjects back to user-facing patterns\n * - Provides lists of patterns by category for stream/consumer setup\n */\nexport class PatternRegistry {\n private readonly logger = new Logger('Jetstream:PatternRegistry');\n private readonly registry = new Map<string, RegisteredHandler>();\n\n public constructor(private readonly options: JetstreamModuleOptions) {}\n\n /**\n * Register all handlers from the NestJS strategy.\n *\n * @param handlers Map of pattern -> MessageHandler from `Server.getHandlers()`.\n */\n public registerHandlers(handlers: Map<string, MessageHandler>): void {\n const serviceName = this.options.name;\n\n for (const [pattern, handler] of handlers) {\n const isEvent = handler.isEventHandler ?? false;\n const isBroadcast = !!(handler.extras as Record<string, unknown> | undefined)?.broadcast;\n\n // Build the full NATS subject this handler should receive\n let fullSubject: string;\n\n if (isBroadcast) {\n fullSubject = buildBroadcastSubject(pattern);\n } else if (isEvent) {\n fullSubject = buildSubject(serviceName, 'ev', pattern);\n } else {\n fullSubject = buildSubject(serviceName, 'cmd', pattern);\n }\n\n this.registry.set(fullSubject, {\n handler,\n pattern,\n isEvent,\n isBroadcast,\n });\n\n let kind: string;\n\n if (isBroadcast) {\n kind = 'broadcast';\n } else if (isEvent) {\n kind = 'event';\n } else {\n kind = 'rpc';\n }\n\n this.logger.debug(`Registered ${kind}: ${pattern} -> ${fullSubject}`);\n }\n\n this.logSummary();\n }\n\n /** Find handler for a full NATS subject. */\n public getHandler(subject: string): MessageHandler | null {\n return this.registry.get(subject)?.handler ?? null;\n }\n\n /** Get all registered broadcast patterns (for consumer filter_subject setup). */\n public getBroadcastPatterns(): string[] {\n return Array.from(this.registry.values())\n .filter((r) => r.isBroadcast)\n .map((r) => `broadcast.${r.pattern}`);\n }\n\n /** Check if any broadcast handlers are registered. */\n public hasBroadcastHandlers(): boolean {\n return Array.from(this.registry.values()).some((r) => r.isBroadcast);\n }\n\n /** Check if any RPC (command) handlers are registered. */\n public hasRpcHandlers(): boolean {\n return Array.from(this.registry.values()).some((r) => !r.isEvent && !r.isBroadcast);\n }\n\n /** Check if any workqueue event handlers are registered. */\n public hasEventHandlers(): boolean {\n return Array.from(this.registry.values()).some((r) => r.isEvent && !r.isBroadcast);\n }\n\n /** Get patterns grouped by kind. */\n public getPatternsByKind(): PatternsByKind {\n const events: string[] = [];\n const commands: string[] = [];\n const broadcasts: string[] = [];\n\n for (const entry of this.registry.values()) {\n if (entry.isBroadcast) broadcasts.push(entry.pattern);\n else if (entry.isEvent) events.push(entry.pattern);\n else commands.push(entry.pattern);\n }\n\n return { events, commands, broadcasts };\n }\n\n /** Normalize a full NATS subject back to the user-facing pattern. */\n public normalizeSubject(subject: string): string {\n const name = internalName(this.options.name);\n const prefixes = [`${name}.cmd.`, `${name}.ev.`, 'broadcast.'];\n\n for (const prefix of prefixes) {\n if (subject.startsWith(prefix)) {\n return subject.slice(prefix.length);\n }\n }\n\n return subject;\n }\n\n /** Log a summary of all registered handlers. */\n private logSummary(): void {\n const { events, commands, broadcasts } = this.getPatternsByKind();\n\n this.logger.log(\n `Registered handlers: ${commands.length} RPC, ${events.length} events, ${broadcasts.length} broadcasts`,\n );\n }\n}\n","import { Logger } from '@nestjs/common';\nimport { JsMsg } from 'nats';\nimport {\n catchError,\n defer,\n EMPTY,\n from,\n isObservable,\n lastValueFrom,\n mergeMap,\n Observable,\n Subscription,\n} from 'rxjs';\n\nimport { RpcContext } from '../../context';\nimport { EventBus } from '../../hooks';\nimport { TransportEvent } from '../../interfaces';\nimport type { Codec, DeadLetterInfo } from '../../interfaces';\n\nimport { MessageProvider } from '../infrastructure';\nimport { PatternRegistry } from './pattern-registry';\n\n/** Options for dead letter queue handling. */\nexport interface DeadLetterConfig {\n /**\n * Map of stream name -> max_deliver value.\n * Used to detect when a message from a given stream has exhausted all delivery attempts.\n */\n maxDeliverByStream: Map<string, number>;\n /** Async callback invoked when a message exhausts all deliveries. */\n onDeadLetter(info: DeadLetterInfo): Promise<void>;\n}\n\n/**\n * Routes incoming event messages (workqueue and broadcast) to NestJS handlers.\n *\n * Delivery semantics (at-least-once):\n * - Handler executes first\n * - Success -> ack (message consumed)\n * - Handler error -> nak (NATS redelivers, up to `max_deliver` times)\n * - Dead letter (max_deliver reached) -> onDeadLetter hook -> term or nak\n * - Decode error -> term (no retry for malformed payloads)\n * - No handler found -> term (configuration error)\n *\n * Both workqueue and broadcast use the same ack/nak semantics.\n * Each durable consumer tracks delivery independently, so a nak from\n * one broadcast consumer does not affect others.\n *\n * Handlers must be idempotent — NATS may redeliver on failure or timeout.\n */\nexport class EventRouter {\n private readonly logger = new Logger('Jetstream:EventRouter');\n private readonly subscriptions: Subscription[] = [];\n\n public constructor(\n private readonly messageProvider: MessageProvider,\n private readonly patternRegistry: PatternRegistry,\n private readonly codec: Codec,\n private readonly eventBus: EventBus,\n private readonly deadLetterConfig?: DeadLetterConfig,\n ) {}\n\n /** Start routing event and broadcast messages to handlers. */\n public start(): void {\n this.subscribeToStream(this.messageProvider.events$, 'workqueue');\n this.subscribeToStream(this.messageProvider.broadcasts$, 'broadcast');\n }\n\n /** Stop routing and unsubscribe from all streams. */\n public destroy(): void {\n for (const sub of this.subscriptions) {\n sub.unsubscribe();\n }\n\n this.subscriptions.length = 0;\n }\n\n /** Subscribe to a message stream and route each message. */\n private subscribeToStream(stream$: Observable<JsMsg>, label: string): void {\n const subscription = stream$\n .pipe(\n mergeMap((msg) =>\n defer(() => this.handle(msg)).pipe(\n catchError((err) => {\n this.logger.error(`Unexpected error in ${label} event router`, err);\n return EMPTY;\n }),\n ),\n ),\n )\n .subscribe();\n\n this.subscriptions.push(subscription);\n }\n\n /** Handle a single event message: decode -> execute handler -> ack/nak. */\n private handle(msg: JsMsg): Observable<void> {\n const handler = this.patternRegistry.getHandler(msg.subject);\n\n if (!handler) {\n msg.term(`No handler for event: ${msg.subject}`);\n this.logger.error(`No handler for event subject: ${msg.subject}`);\n return EMPTY;\n }\n\n let data: unknown;\n\n try {\n data = this.codec.decode(msg.data);\n } catch (err) {\n msg.term('Decode error');\n this.logger.error(`Decode error for ${msg.subject}:`, err);\n return EMPTY;\n }\n\n this.eventBus.emit(TransportEvent.MessageRouted, msg.subject, 'event');\n\n const ctx = new RpcContext([msg]);\n\n return from(this.executeHandler(handler, data, ctx, msg));\n }\n\n /** Execute handler, then ack on success or nak/dead-letter on failure. */\n private async executeHandler(\n handler: (data: unknown, ctx: RpcContext) => Promise<unknown>,\n data: unknown,\n ctx: RpcContext,\n msg: JsMsg,\n ): Promise<void> {\n try {\n const result = await handler(data, ctx);\n\n if (isObservable(result)) {\n await lastValueFrom(result, { defaultValue: undefined });\n }\n\n msg.ack();\n } catch (err) {\n this.logger.error(`Event handler error (${msg.subject}):`, err);\n\n if (this.isDeadLetter(msg)) {\n await this.handleDeadLetter(msg, data, err);\n } else {\n msg.nak();\n }\n }\n }\n\n /** Check if the message has exhausted all delivery attempts. */\n private isDeadLetter(msg: JsMsg): boolean {\n if (!this.deadLetterConfig) return false;\n\n const maxDeliver = this.deadLetterConfig.maxDeliverByStream.get(msg.info.stream);\n\n if (maxDeliver === undefined) return false;\n\n return msg.info.deliveryCount >= maxDeliver;\n }\n\n /** Handle a dead letter: invoke callback, then term or nak based on result. */\n private async handleDeadLetter(msg: JsMsg, data: unknown, error: unknown): Promise<void> {\n const info: DeadLetterInfo = {\n subject: msg.subject,\n data,\n headers: msg.headers,\n error,\n deliveryCount: msg.info.deliveryCount,\n stream: msg.info.stream,\n streamSequence: msg.info.streamSequence,\n timestamp: new Date(msg.info.timestampNanos / 1_000_000).toISOString(),\n };\n\n this.eventBus.emit(TransportEvent.DeadLetter, info);\n\n if (!this.deadLetterConfig) return;\n\n try {\n await this.deadLetterConfig.onDeadLetter(info);\n msg.term('Dead letter processed');\n } catch (hookErr) {\n this.logger.error(`onDeadLetter callback failed for ${msg.subject}, nak for retry:`, hookErr);\n msg.nak();\n }\n }\n}\n","import { Logger } from '@nestjs/common';\nimport { MessageHandler } from '@nestjs/microservices';\nimport { headers, JsMsg } from 'nats';\nimport { catchError, defer, EMPTY, from, mergeMap, Observable, Subscription } from 'rxjs';\n\nimport { ConnectionProvider } from '../../connection';\nimport { RpcContext } from '../../context';\nimport { EventBus } from '../../hooks';\nimport { TransportEvent } from '../../interfaces';\nimport type { Codec } from '../../interfaces';\nimport { DEFAULT_JETSTREAM_RPC_TIMEOUT, JetstreamHeader } from '../../jetstream.constants';\nimport { serializeError, unwrapResult } from '../../utils';\n\nimport { MessageProvider } from '../infrastructure';\nimport { PatternRegistry } from './pattern-registry';\n\n/**\n * Routes RPC command messages in JetStream mode.\n *\n * Delivery semantics:\n * - Handler must complete within timeout (default: 3 min)\n * - Success -> ack -> publish response to ReplyTo (publish failure does not affect ack)\n * - Handler error -> publish error to ReplyTo -> term (no redelivery)\n * - Timeout -> no response -> term\n * - No handler / decode error -> term immediately\n *\n * Nak is never used for RPC — prevents duplicate side effects.\n */\nexport class RpcRouter {\n private readonly logger = new Logger('Jetstream:RpcRouter');\n private readonly timeout: number;\n private subscription: Subscription | null = null;\n\n public constructor(\n private readonly messageProvider: MessageProvider,\n private readonly patternRegistry: PatternRegistry,\n private readonly connection: ConnectionProvider,\n private readonly codec: Codec,\n private readonly eventBus: EventBus,\n timeout?: number,\n ) {\n this.timeout = timeout ?? DEFAULT_JETSTREAM_RPC_TIMEOUT;\n }\n\n /** Start routing command messages to handlers. */\n public start(): void {\n this.subscription = this.messageProvider.commands$\n .pipe(\n mergeMap((msg) =>\n defer(() => this.handle(msg)).pipe(\n catchError((err) => {\n this.logger.error('Unexpected error in RPC router', err);\n return EMPTY;\n }),\n ),\n ),\n )\n .subscribe();\n }\n\n /** Stop routing and unsubscribe. */\n public destroy(): void {\n this.subscription?.unsubscribe();\n this.subscription = null;\n }\n\n /** Handle a single RPC command message. */\n private handle(msg: JsMsg): Observable<void> {\n const handler = this.patternRegistry.getHandler(msg.subject);\n\n if (!handler) {\n msg.term(`No handler for RPC: ${msg.subject}`);\n this.logger.error(`No handler for RPC subject: ${msg.subject}`);\n return EMPTY;\n }\n\n const replyTo = msg.headers?.get(JetstreamHeader.ReplyTo);\n const correlationId = msg.headers?.get(JetstreamHeader.CorrelationId);\n\n if (!replyTo || !correlationId) {\n msg.term('Missing required headers (reply-to or correlation-id)');\n this.logger.error(`Missing headers for RPC: ${msg.subject}`);\n return EMPTY;\n }\n\n let data: unknown;\n\n try {\n data = this.codec.decode(msg.data);\n } catch (err) {\n msg.term('Decode error');\n this.logger.error(`Decode error for RPC ${msg.subject}:`, err);\n return EMPTY;\n }\n\n this.eventBus.emit(TransportEvent.MessageRouted, msg.subject, 'rpc');\n\n return from(this.executeHandler(handler, data, msg, replyTo, correlationId));\n }\n\n /** Execute handler, publish response, settle message. */\n private async executeHandler(\n handler: MessageHandler,\n data: unknown,\n msg: JsMsg,\n replyTo: string,\n correlationId: string,\n ): Promise<void> {\n const nc = await this.connection.getConnection();\n const ctx = new RpcContext([msg]);\n\n const hdrs = headers();\n\n hdrs.set(JetstreamHeader.CorrelationId, correlationId);\n\n let settled = false;\n\n // Race handler against timeout\n const timeoutId = setTimeout(() => {\n if (settled) return;\n settled = true;\n this.logger.error(`RPC timeout (${this.timeout}ms): ${msg.subject}`);\n this.eventBus.emit(TransportEvent.RpcTimeout, msg.subject, correlationId);\n msg.term('Handler timeout');\n }, this.timeout);\n\n try {\n const result = await unwrapResult(handler(data, ctx));\n\n // settled may be set by the setTimeout callback above (async race)\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (settled) return;\n settled = true;\n clearTimeout(timeoutId);\n\n // Ack first — handler succeeded, message is processed regardless of\n // whether we can deliver the response back to the caller.\n msg.ack();\n\n try {\n nc.publish(replyTo, this.codec.encode(result), { headers: hdrs });\n } catch (publishErr) {\n this.logger.error(`Failed to publish RPC response for ${msg.subject}`, publishErr);\n }\n } catch (err) {\n if (settled) return;\n settled = true;\n clearTimeout(timeoutId);\n\n // Publish error response with x-error header\n try {\n hdrs.set(JetstreamHeader.Error, 'true');\n nc.publish(replyTo, this.codec.encode(serializeError(err)), { headers: hdrs });\n } catch (encodeErr) {\n this.logger.error(`Failed to encode RPC error for ${msg.subject}`, encodeErr);\n }\n\n msg.term(`Handler error: ${msg.subject}`);\n }\n }\n}\n","import { Logger } from '@nestjs/common';\n\nimport { ConnectionProvider } from '../connection';\nimport { EventBus } from '../hooks';\nimport { TransportEvent } from '../interfaces';\nimport { JetstreamStrategy } from '../server/strategy';\n\n/**\n * Orchestrates graceful transport shutdown.\n *\n * Shutdown sequence:\n * 1. Emit onShutdownStart hook\n * 2. Stop accepting new messages (close subscriptions, stop consumers)\n * 3. Wait for in-flight handlers to complete (up to timeout)\n * 4. Drain and close NATS connection\n * 5. Emit onShutdownComplete hook\n */\nexport class ShutdownManager {\n private readonly logger = new Logger('Jetstream:Shutdown');\n\n public constructor(\n private readonly connection: ConnectionProvider,\n private readonly eventBus: EventBus,\n private readonly timeout: number,\n ) {}\n\n /**\n * Execute the full shutdown sequence.\n *\n * @param strategy Optional strategy to close (stops consumers and subscriptions).\n */\n public async shutdown(strategy?: JetstreamStrategy): Promise<void> {\n this.eventBus.emit(TransportEvent.ShutdownStart);\n this.logger.log(`Graceful shutdown started (timeout: ${this.timeout}ms)`);\n\n // 1. Stop accepting new messages (close subscriptions, stop consumers)\n strategy?.close();\n\n // 2. Drain and close NATS connection.\n // NATS drain() waits for in-flight messages and pending subscriptions,\n // then closes the connection. We add a timeout as a safety net.\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n try {\n await Promise.race([\n this.connection.shutdown(),\n new Promise<void>((resolve) => {\n timeoutId = setTimeout(resolve, this.timeout);\n }),\n ]);\n } finally {\n clearTimeout(timeoutId);\n }\n\n this.eventBus.emit(TransportEvent.ShutdownComplete);\n this.logger.log('Graceful shutdown complete');\n }\n}\n"],"mappings":"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","names":["import_common","import_nats","TransportEvent","JetstreamHeader","headers","natsHeaders","import_nats","NatsJSONCodec","import_common","import_nats","import_common","import_microservices","import_common","import_nats","import_microservices","import_microservices","import_rxjs","err","natsHeaders","import_common","import_nats","import_common","import_nats","import_common","import_rxjs","import_common","import_common","import_rxjs","import_common","import_nats","import_rxjs","import_common"]}
|