@lokative/messaging 0.1.1 → 1.1.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.
Files changed (54) hide show
  1. package/README.md +49 -12
  2. package/dist/cjs/index.d.ts +6 -0
  3. package/dist/cjs/index.js +14 -0
  4. package/dist/cjs/kafka.d.ts +1 -0
  5. package/dist/cjs/kafka.js +5 -0
  6. package/dist/cjs/messaging.config.d.ts +15 -0
  7. package/dist/cjs/messaging.config.js +2 -0
  8. package/dist/cjs/messaging.decorator.d.ts +2 -0
  9. package/dist/cjs/messaging.decorator.js +20 -0
  10. package/dist/cjs/messaging.module.d.ts +5 -0
  11. package/dist/cjs/messaging.module.js +34 -0
  12. package/dist/cjs/messaging.publisher.d.ts +6 -0
  13. package/dist/cjs/messaging.publisher.js +32 -0
  14. package/dist/cjs/messaging.registry.d.ts +12 -0
  15. package/dist/cjs/messaging.registry.js +67 -0
  16. package/dist/cjs/nats.d.ts +1 -0
  17. package/dist/cjs/nats.js +5 -0
  18. package/dist/cjs/redis.d.ts +1 -0
  19. package/dist/cjs/redis.js +5 -0
  20. package/dist/cjs/transport.interface.d.ts +18 -0
  21. package/dist/cjs/transport.interface.js +4 -0
  22. package/dist/cjs/transports/kafka.transport.d.ts +15 -0
  23. package/dist/cjs/transports/kafka.transport.js +82 -0
  24. package/dist/cjs/transports/nats.transport.d.ts +20 -0
  25. package/dist/cjs/transports/nats.transport.js +90 -0
  26. package/dist/cjs/transports/redis.transport.d.ts +16 -0
  27. package/dist/cjs/transports/redis.transport.js +71 -0
  28. package/dist/esm/index.d.ts +6 -0
  29. package/dist/esm/index.js +5 -0
  30. package/dist/esm/kafka.d.ts +1 -0
  31. package/dist/esm/kafka.js +1 -0
  32. package/dist/esm/messaging.config.d.ts +15 -0
  33. package/dist/esm/messaging.config.js +1 -0
  34. package/dist/esm/messaging.decorator.d.ts +2 -0
  35. package/dist/esm/messaging.decorator.js +16 -0
  36. package/dist/esm/messaging.module.d.ts +5 -0
  37. package/dist/esm/messaging.module.js +31 -0
  38. package/dist/esm/messaging.publisher.d.ts +6 -0
  39. package/dist/esm/messaging.publisher.js +29 -0
  40. package/dist/esm/messaging.registry.d.ts +12 -0
  41. package/dist/esm/messaging.registry.js +64 -0
  42. package/dist/esm/nats.d.ts +1 -0
  43. package/dist/esm/nats.js +1 -0
  44. package/dist/esm/redis.d.ts +1 -0
  45. package/dist/esm/redis.js +1 -0
  46. package/dist/esm/transport.interface.d.ts +18 -0
  47. package/dist/esm/transport.interface.js +1 -0
  48. package/dist/esm/transports/kafka.transport.d.ts +15 -0
  49. package/dist/esm/transports/kafka.transport.js +79 -0
  50. package/dist/esm/transports/nats.transport.d.ts +20 -0
  51. package/dist/esm/transports/nats.transport.js +87 -0
  52. package/dist/esm/transports/redis.transport.d.ts +16 -0
  53. package/dist/esm/transports/redis.transport.js +68 -0
  54. package/package.json +27 -7
package/README.md CHANGED
@@ -23,13 +23,30 @@ npm install redis
23
23
 
24
24
  ---
25
25
 
26
+ ## Imports
27
+
28
+ Transports are isolated behind subpath exports so only the dependency you use gets loaded:
29
+
30
+ ```typescript
31
+ // Core (always needed)
32
+ import { MessagingModule, MessagingPublisher, Incoming, Outgoing } from '@lokative/messaging';
33
+
34
+ // Pick one transport
35
+ import { NatsTransport } from '@lokative/messaging/nats';
36
+ import { KafkaTransport } from '@lokative/messaging/kafka';
37
+ import { RedisTransport } from '@lokative/messaging/redis';
38
+ ```
39
+
40
+ ---
41
+
26
42
  ## Quick Start
27
43
 
28
44
  ### NATS JetStream
29
45
 
30
46
  ```typescript
31
47
  import { Module } from '@nestjs/common';
32
- import { MessagingModule, NatsTransport } from '@lokative/messaging';
48
+ import { MessagingModule } from '@lokative/messaging';
49
+ import { NatsTransport } from '@lokative/messaging/nats';
33
50
 
34
51
  @Module({
35
52
  imports: [
@@ -54,7 +71,8 @@ export class AppModule {}
54
71
 
55
72
  ```typescript
56
73
  import { Module } from '@nestjs/common';
57
- import { MessagingModule, KafkaTransport } from '@lokative/messaging';
74
+ import { MessagingModule } from '@lokative/messaging';
75
+ import { KafkaTransport } from '@lokative/messaging/kafka';
58
76
 
59
77
  @Module({
60
78
  imports: [
@@ -77,7 +95,8 @@ export class AppModule {}
77
95
 
78
96
  ```typescript
79
97
  import { Module } from '@nestjs/common';
80
- import { MessagingModule, RedisTransport } from '@lokative/messaging';
98
+ import { MessagingModule } from '@lokative/messaging';
99
+ import { RedisTransport } from '@lokative/messaging/redis';
81
100
 
82
101
  @Module({
83
102
  imports: [
@@ -309,7 +328,8 @@ interface SubscribeOptions {
309
328
  ```typescript
310
329
  // app.module.ts
311
330
  import { Module } from '@nestjs/common';
312
- import { MessagingModule, NatsTransport } from '@lokative/messaging';
331
+ import { MessagingModule } from '@lokative/messaging';
332
+ import { NatsTransport } from '@lokative/messaging/nats';
313
333
  import { OrderModule } from './order/order.module';
314
334
 
315
335
  @Module({
@@ -390,7 +410,7 @@ export class OrderHandler {
390
410
  To switch this app to Kafka, change only the module registration:
391
411
 
392
412
  ```typescript
393
- import { KafkaTransport } from '@lokative/messaging';
413
+ import { KafkaTransport } from '@lokative/messaging/kafka';
394
414
 
395
415
  MessagingModule.register({
396
416
  transport: KafkaTransport,
@@ -405,7 +425,7 @@ MessagingModule.register({
405
425
  Or to Redis:
406
426
 
407
427
  ```typescript
408
- import { RedisTransport } from '@lokative/messaging';
428
+ import { RedisTransport } from '@lokative/messaging/redis';
409
429
 
410
430
  MessagingModule.register({
411
431
  transport: RedisTransport,
@@ -421,6 +441,8 @@ No changes needed in services or handlers.
421
441
 
422
442
  ### Exports
423
443
 
444
+ From `@lokative/messaging`:
445
+
424
446
  | Export | Type | Description |
425
447
  | -------------------------- | ----------- | ---------------------------------------------- |
426
448
  | `MessagingModule` | Module | NestJS dynamic module |
@@ -432,15 +454,30 @@ No changes needed in services or handlers.
432
454
  | `Subscription` | Interface | Async-iterable subscription |
433
455
  | `SubscribeOptions` | Interface | Options passed to `subscribe()` |
434
456
  | `MESSAGING_TRANSPORT` | Token | DI token for the transport provider |
435
- | `NatsTransport` | Injectable | Built-in NATS JetStream transport |
436
- | `NatsTransportOptions` | Interface | Options for `NatsTransport` |
437
- | `KafkaTransport` | Injectable | Built-in Kafka transport |
438
- | `KafkaTransportOptions` | Interface | Options for `KafkaTransport` |
439
- | `RedisTransport` | Injectable | Built-in Redis Pub/Sub transport |
440
- | `RedisTransportOptions` | Interface | Options for `RedisTransport` |
441
457
  | `Incoming` | Decorator | Subscribe a method to a subject |
442
458
  | `Outgoing` | Decorator | Auto-publish a method's return value |
443
459
 
460
+ From `@lokative/messaging/nats`:
461
+
462
+ | Export | Type | Description |
463
+ | --------------------- | ----------- | --------------------------------- |
464
+ | `NatsTransport` | Injectable | Built-in NATS JetStream transport |
465
+ | `NatsTransportOptions`| Interface | Options for `NatsTransport` |
466
+
467
+ From `@lokative/messaging/kafka`:
468
+
469
+ | Export | Type | Description |
470
+ | ---------------------- | ----------- | -------------------------- |
471
+ | `KafkaTransport` | Injectable | Built-in Kafka transport |
472
+ | `KafkaTransportOptions`| Interface | Options for `KafkaTransport` |
473
+
474
+ From `@lokative/messaging/redis`:
475
+
476
+ | Export | Type | Description |
477
+ | ---------------------- | ----------- | -------------------------------- |
478
+ | `RedisTransport` | Injectable | Built-in Redis Pub/Sub transport |
479
+ | `RedisTransportOptions`| Interface | Options for `RedisTransport` |
480
+
444
481
  ### Injection
445
482
 
446
483
  ```typescript
@@ -0,0 +1,6 @@
1
+ export { MessagingConfig } from './messaging.config';
2
+ export { MessagingTransport, MessageEnvelope, Subscription, SubscribeOptions, MESSAGING_TRANSPORT } from './transport.interface';
3
+ export { Incoming, Outgoing } from './messaging.decorator';
4
+ export { MessagingModule } from './messaging.module';
5
+ export { MessagingPublisher } from './messaging.publisher';
6
+ export { MessagingConsumerRegistry } from './messaging.registry';
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MessagingConsumerRegistry = exports.MessagingPublisher = exports.MessagingModule = exports.Outgoing = exports.Incoming = exports.MESSAGING_TRANSPORT = void 0;
4
+ var transport_interface_1 = require("./transport.interface");
5
+ Object.defineProperty(exports, "MESSAGING_TRANSPORT", { enumerable: true, get: function () { return transport_interface_1.MESSAGING_TRANSPORT; } });
6
+ var messaging_decorator_1 = require("./messaging.decorator");
7
+ Object.defineProperty(exports, "Incoming", { enumerable: true, get: function () { return messaging_decorator_1.Incoming; } });
8
+ Object.defineProperty(exports, "Outgoing", { enumerable: true, get: function () { return messaging_decorator_1.Outgoing; } });
9
+ var messaging_module_1 = require("./messaging.module");
10
+ Object.defineProperty(exports, "MessagingModule", { enumerable: true, get: function () { return messaging_module_1.MessagingModule; } });
11
+ var messaging_publisher_1 = require("./messaging.publisher");
12
+ Object.defineProperty(exports, "MessagingPublisher", { enumerable: true, get: function () { return messaging_publisher_1.MessagingPublisher; } });
13
+ var messaging_registry_1 = require("./messaging.registry");
14
+ Object.defineProperty(exports, "MessagingConsumerRegistry", { enumerable: true, get: function () { return messaging_registry_1.MessagingConsumerRegistry; } });
@@ -0,0 +1 @@
1
+ export { KafkaTransport, KafkaTransportOptions } from './transports/kafka.transport';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KafkaTransport = void 0;
4
+ var kafka_transport_1 = require("./transports/kafka.transport");
5
+ Object.defineProperty(exports, "KafkaTransport", { enumerable: true, get: function () { return kafka_transport_1.KafkaTransport; } });
@@ -0,0 +1,15 @@
1
+ import type { Type } from '@nestjs/common';
2
+ import type { MessagingTransport } from './transport.interface';
3
+ export interface MessagingConfig {
4
+ transport: Type<MessagingTransport>;
5
+ transportOptions?: Record<string, any>;
6
+ streams?: {
7
+ name: string;
8
+ subjects: string[];
9
+ }[];
10
+ consumers?: {
11
+ group?: string;
12
+ retry?: number;
13
+ dlq?: boolean;
14
+ };
15
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export declare function Incoming(subject: string): MethodDecorator;
2
+ export declare function Outgoing(subject: string): MethodDecorator;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Incoming = Incoming;
4
+ exports.Outgoing = Outgoing;
5
+ function Incoming(subject) {
6
+ return (target, key) => {
7
+ Reflect.defineMetadata("msg:incoming", { subject }, target[key]);
8
+ };
9
+ }
10
+ function Outgoing(subject) {
11
+ return (target, key, descriptor) => {
12
+ const original = descriptor.value;
13
+ descriptor.value = async function (...args) {
14
+ const result = await original.apply(this, args);
15
+ const publisher = this.publisher;
16
+ await publisher.publish(subject, result);
17
+ return result;
18
+ };
19
+ };
20
+ }
@@ -0,0 +1,5 @@
1
+ import { DynamicModule } from "@nestjs/common";
2
+ import { MessagingConfig } from "./messaging.config";
3
+ export declare class MessagingModule {
4
+ static register(config: MessagingConfig): DynamicModule;
5
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var MessagingModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.MessagingModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const core_1 = require("@nestjs/core");
13
+ const transport_interface_1 = require("./transport.interface");
14
+ const messaging_publisher_1 = require("./messaging.publisher");
15
+ const messaging_registry_1 = require("./messaging.registry");
16
+ let MessagingModule = MessagingModule_1 = class MessagingModule {
17
+ static register(config) {
18
+ return {
19
+ module: MessagingModule_1,
20
+ imports: [core_1.DiscoveryModule],
21
+ providers: [
22
+ { provide: "MSG_CONFIG", useValue: config },
23
+ { provide: transport_interface_1.MESSAGING_TRANSPORT, useClass: config.transport },
24
+ messaging_publisher_1.MessagingPublisher,
25
+ messaging_registry_1.MessagingConsumerRegistry,
26
+ ],
27
+ exports: [messaging_publisher_1.MessagingPublisher],
28
+ };
29
+ }
30
+ };
31
+ exports.MessagingModule = MessagingModule;
32
+ exports.MessagingModule = MessagingModule = MessagingModule_1 = __decorate([
33
+ (0, common_1.Module)({})
34
+ ], MessagingModule);
@@ -0,0 +1,6 @@
1
+ import { MessagingTransport } from "./transport.interface";
2
+ export declare class MessagingPublisher {
3
+ private transport;
4
+ constructor(transport: MessagingTransport);
5
+ publish(subject: string, payload: any): Promise<void>;
6
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.MessagingPublisher = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const transport_interface_1 = require("./transport.interface");
18
+ let MessagingPublisher = class MessagingPublisher {
19
+ transport;
20
+ constructor(transport) {
21
+ this.transport = transport;
22
+ }
23
+ async publish(subject, payload) {
24
+ await this.transport.publish(subject, payload);
25
+ }
26
+ };
27
+ exports.MessagingPublisher = MessagingPublisher;
28
+ exports.MessagingPublisher = MessagingPublisher = __decorate([
29
+ (0, common_1.Injectable)(),
30
+ __param(0, (0, common_1.Inject)(transport_interface_1.MESSAGING_TRANSPORT)),
31
+ __metadata("design:paramtypes", [Object])
32
+ ], MessagingPublisher);
@@ -0,0 +1,12 @@
1
+ import { OnModuleInit } from "@nestjs/common";
2
+ import { DiscoveryService } from "@nestjs/core/discovery";
3
+ import { MessagingTransport } from "./transport.interface";
4
+ import type { MessagingConfig } from "./messaging.config";
5
+ export declare class MessagingConsumerRegistry implements OnModuleInit {
6
+ private transport;
7
+ private discovery;
8
+ private config;
9
+ constructor(transport: MessagingTransport, discovery: DiscoveryService, config: MessagingConfig);
10
+ onModuleInit(): Promise<void>;
11
+ private startConsumer;
12
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.MessagingConsumerRegistry = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const discovery_1 = require("@nestjs/core/discovery");
18
+ const transport_interface_1 = require("./transport.interface");
19
+ let MessagingConsumerRegistry = class MessagingConsumerRegistry {
20
+ transport;
21
+ discovery;
22
+ config;
23
+ constructor(transport, discovery, config) {
24
+ this.transport = transport;
25
+ this.discovery = discovery;
26
+ this.config = config;
27
+ }
28
+ async onModuleInit() {
29
+ await this.transport.connect();
30
+ const providers = this.discovery.getProviders();
31
+ for (const provider of providers) {
32
+ const instance = provider.instance;
33
+ if (!instance)
34
+ continue;
35
+ const proto = Object.getPrototypeOf(instance);
36
+ for (const key of Object.getOwnPropertyNames(proto)) {
37
+ const handler = instance[key];
38
+ if (typeof handler !== 'function')
39
+ continue;
40
+ const meta = Reflect.getMetadata("msg:incoming", handler);
41
+ if (!meta)
42
+ continue;
43
+ this.startConsumer(instance, handler, meta);
44
+ }
45
+ }
46
+ }
47
+ async startConsumer(instance, handler, meta) {
48
+ const group = this.config.consumers?.group;
49
+ const sub = await this.transport.subscribe(meta.subject, { group });
50
+ for await (const msg of sub) {
51
+ try {
52
+ await handler.call(instance, msg.data);
53
+ msg.ack();
54
+ }
55
+ catch {
56
+ msg.nak();
57
+ }
58
+ }
59
+ }
60
+ };
61
+ exports.MessagingConsumerRegistry = MessagingConsumerRegistry;
62
+ exports.MessagingConsumerRegistry = MessagingConsumerRegistry = __decorate([
63
+ (0, common_1.Injectable)(),
64
+ __param(0, (0, common_1.Inject)(transport_interface_1.MESSAGING_TRANSPORT)),
65
+ __param(2, (0, common_1.Inject)("MSG_CONFIG")),
66
+ __metadata("design:paramtypes", [Object, discovery_1.DiscoveryService, Object])
67
+ ], MessagingConsumerRegistry);
@@ -0,0 +1 @@
1
+ export { NatsTransport, NatsTransportOptions } from './transports/nats.transport';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NatsTransport = void 0;
4
+ var nats_transport_1 = require("./transports/nats.transport");
5
+ Object.defineProperty(exports, "NatsTransport", { enumerable: true, get: function () { return nats_transport_1.NatsTransport; } });
@@ -0,0 +1 @@
1
+ export { RedisTransport, RedisTransportOptions } from './transports/redis.transport';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedisTransport = void 0;
4
+ var redis_transport_1 = require("./transports/redis.transport");
5
+ Object.defineProperty(exports, "RedisTransport", { enumerable: true, get: function () { return redis_transport_1.RedisTransport; } });
@@ -0,0 +1,18 @@
1
+ export interface MessageEnvelope {
2
+ subject: string;
3
+ data: any;
4
+ ack(): void;
5
+ nak(): void;
6
+ }
7
+ export interface Subscription {
8
+ [Symbol.asyncIterator](): AsyncIterator<MessageEnvelope>;
9
+ }
10
+ export interface MessagingTransport {
11
+ connect(): Promise<void>;
12
+ publish(subject: string, payload: any): Promise<void>;
13
+ subscribe(subject: string, options?: SubscribeOptions): Promise<Subscription>;
14
+ }
15
+ export interface SubscribeOptions {
16
+ group?: string;
17
+ }
18
+ export declare const MESSAGING_TRANSPORT = "MESSAGING_TRANSPORT";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MESSAGING_TRANSPORT = void 0;
4
+ exports.MESSAGING_TRANSPORT = 'MESSAGING_TRANSPORT';
@@ -0,0 +1,15 @@
1
+ import type { MessagingTransport, Subscription, SubscribeOptions } from '../transport.interface';
2
+ import type { MessagingConfig } from '../messaging.config';
3
+ export interface KafkaTransportOptions {
4
+ brokers: string[];
5
+ clientId?: string;
6
+ }
7
+ export declare class KafkaTransport implements MessagingTransport {
8
+ private config;
9
+ private kafka;
10
+ private producer;
11
+ constructor(config: MessagingConfig);
12
+ connect(): Promise<void>;
13
+ publish(subject: string, payload: any): Promise<void>;
14
+ subscribe(subject: string, options?: SubscribeOptions): Promise<Subscription>;
15
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.KafkaTransport = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const kafkajs_1 = require("kafkajs");
18
+ let KafkaTransport = class KafkaTransport {
19
+ config;
20
+ kafka;
21
+ producer;
22
+ constructor(config) {
23
+ this.config = config;
24
+ }
25
+ async connect() {
26
+ const opts = this.config.transportOptions;
27
+ this.kafka = new kafkajs_1.Kafka({
28
+ clientId: opts.clientId ?? 'nestjs-app',
29
+ brokers: opts.brokers,
30
+ });
31
+ this.producer = this.kafka.producer();
32
+ await this.producer.connect();
33
+ }
34
+ async publish(subject, payload) {
35
+ await this.producer.send({
36
+ topic: subject,
37
+ messages: [{ value: JSON.stringify(payload) }],
38
+ });
39
+ }
40
+ async subscribe(subject, options) {
41
+ const consumer = this.kafka.consumer({
42
+ groupId: options?.group ?? 'nest-consumer',
43
+ });
44
+ await consumer.connect();
45
+ await consumer.subscribe({ topic: subject, fromBeginning: false });
46
+ const buffer = [];
47
+ let waiting = null;
48
+ await consumer.run({
49
+ eachMessage: async ({ topic, message }) => {
50
+ const envelope = {
51
+ subject: topic,
52
+ data: JSON.parse(message.value?.toString() ?? '{}'),
53
+ ack: () => { }, // kafkajs auto-commits offsets
54
+ nak: () => { },
55
+ };
56
+ if (waiting) {
57
+ const resolve = waiting;
58
+ waiting = null;
59
+ resolve({ done: false, value: envelope });
60
+ }
61
+ else {
62
+ buffer.push(envelope);
63
+ }
64
+ },
65
+ });
66
+ const iterator = {
67
+ next() {
68
+ if (buffer.length > 0) {
69
+ return Promise.resolve({ done: false, value: buffer.shift() });
70
+ }
71
+ return new Promise(r => { waiting = r; });
72
+ },
73
+ };
74
+ return { [Symbol.asyncIterator]: () => iterator };
75
+ }
76
+ };
77
+ exports.KafkaTransport = KafkaTransport;
78
+ exports.KafkaTransport = KafkaTransport = __decorate([
79
+ (0, common_1.Injectable)(),
80
+ __param(0, (0, common_1.Inject)('MSG_CONFIG')),
81
+ __metadata("design:paramtypes", [Object])
82
+ ], KafkaTransport);
@@ -0,0 +1,20 @@
1
+ import type { MessagingTransport, Subscription, SubscribeOptions } from '../transport.interface';
2
+ import type { MessagingConfig } from '../messaging.config';
3
+ export interface NatsTransportOptions {
4
+ servers: string[];
5
+ streams?: {
6
+ name: string;
7
+ subjects: string[];
8
+ }[];
9
+ }
10
+ export declare class NatsTransport implements MessagingTransport {
11
+ private config;
12
+ private nc;
13
+ private js;
14
+ private jsm;
15
+ constructor(config: MessagingConfig);
16
+ connect(): Promise<void>;
17
+ publish(subject: string, payload: any): Promise<void>;
18
+ subscribe(subject: string, options?: SubscribeOptions): Promise<Subscription>;
19
+ private ensureStreams;
20
+ }
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.NatsTransport = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const nats_1 = require("nats");
18
+ let NatsTransport = class NatsTransport {
19
+ config;
20
+ nc;
21
+ js;
22
+ jsm;
23
+ constructor(config) {
24
+ this.config = config;
25
+ }
26
+ async connect() {
27
+ const opts = this.config.transportOptions;
28
+ this.nc = await (0, nats_1.connect)({ servers: opts.servers });
29
+ this.js = this.nc.jetstream();
30
+ this.jsm = await this.nc.jetstreamManager();
31
+ await this.ensureStreams(opts.streams ?? this.config.streams ?? []);
32
+ }
33
+ async publish(subject, payload) {
34
+ await this.js.publish(subject, Buffer.from(JSON.stringify(payload)));
35
+ }
36
+ async subscribe(subject, options) {
37
+ const durable = options?.group ?? 'nest-consumer';
38
+ const opts = (0, nats_1.consumerOpts)();
39
+ opts.durable(durable);
40
+ opts.ackExplicit();
41
+ opts.deliverTo(durable);
42
+ const sub = await this.js.subscribe(subject, opts);
43
+ const iterator = {
44
+ async next() {
45
+ const result = await sub[Symbol.asyncIterator]().next();
46
+ if (result.done)
47
+ return { done: true, value: undefined };
48
+ const msg = result.value;
49
+ return {
50
+ done: false,
51
+ value: {
52
+ subject: msg.subject,
53
+ data: JSON.parse(msg.data.toString()),
54
+ ack: () => msg.ack(),
55
+ nak: () => msg.nak(),
56
+ },
57
+ };
58
+ },
59
+ };
60
+ return { [Symbol.asyncIterator]: () => iterator };
61
+ }
62
+ async ensureStreams(streams) {
63
+ for (const stream of streams) {
64
+ try {
65
+ const info = await this.jsm.streams.info(stream.name);
66
+ const existing = info.config.subjects ?? [];
67
+ const missing = stream.subjects.filter(s => !existing.includes(s));
68
+ if (missing.length > 0) {
69
+ info.config.subjects = [...existing, ...missing];
70
+ await this.jsm.streams.update(stream.name, info.config);
71
+ }
72
+ }
73
+ catch {
74
+ try {
75
+ await this.jsm.streams.add({ name: stream.name, subjects: stream.subjects });
76
+ }
77
+ catch (addErr) {
78
+ if (addErr?.api_error?.err_code !== 10065)
79
+ throw addErr;
80
+ }
81
+ }
82
+ }
83
+ }
84
+ };
85
+ exports.NatsTransport = NatsTransport;
86
+ exports.NatsTransport = NatsTransport = __decorate([
87
+ (0, common_1.Injectable)(),
88
+ __param(0, (0, common_1.Inject)('MSG_CONFIG')),
89
+ __metadata("design:paramtypes", [Object])
90
+ ], NatsTransport);
@@ -0,0 +1,16 @@
1
+ import type { MessagingTransport, Subscription, SubscribeOptions } from '../transport.interface';
2
+ import type { MessagingConfig } from '../messaging.config';
3
+ export interface RedisTransportOptions {
4
+ url?: string;
5
+ host?: string;
6
+ port?: number;
7
+ }
8
+ export declare class RedisTransport implements MessagingTransport {
9
+ private config;
10
+ private pub;
11
+ private sub;
12
+ constructor(config: MessagingConfig);
13
+ connect(): Promise<void>;
14
+ publish(subject: string, payload: any): Promise<void>;
15
+ subscribe(subject: string, _options?: SubscribeOptions): Promise<Subscription>;
16
+ }