@loipv/nestjs-kafka 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +377 -0
  2. package/dist/consumer.module.d.ts +10 -0
  3. package/dist/consumer.module.js +38 -0
  4. package/dist/consumer.module.js.map +1 -0
  5. package/dist/decorators/constants.d.ts +1 -0
  6. package/dist/decorators/constants.js +5 -0
  7. package/dist/decorators/constants.js.map +1 -0
  8. package/dist/decorators/consumer.decorator.d.ts +8 -0
  9. package/dist/decorators/consumer.decorator.js +16 -0
  10. package/dist/decorators/consumer.decorator.js.map +1 -0
  11. package/dist/decorators/index.d.ts +2 -0
  12. package/dist/decorators/index.js +21 -0
  13. package/dist/decorators/index.js.map +1 -0
  14. package/dist/discovery/consumer-discovery.service.d.ts +14 -0
  15. package/dist/discovery/consumer-discovery.service.js +82 -0
  16. package/dist/discovery/consumer-discovery.service.js.map +1 -0
  17. package/dist/discovery/index.d.ts +1 -0
  18. package/dist/discovery/index.js +18 -0
  19. package/dist/discovery/index.js.map +1 -0
  20. package/dist/health/index.d.ts +1 -0
  21. package/dist/health/index.js +18 -0
  22. package/dist/health/index.js.map +1 -0
  23. package/dist/health/kafka-health-indicator.d.ts +12 -0
  24. package/dist/health/kafka-health-indicator.js +98 -0
  25. package/dist/health/kafka-health-indicator.js.map +1 -0
  26. package/dist/index.d.ts +6 -0
  27. package/dist/index.js +29 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/interfaces/consumer-options.interface.d.ts +52 -0
  30. package/dist/interfaces/consumer-options.interface.js +3 -0
  31. package/dist/interfaces/consumer-options.interface.js.map +1 -0
  32. package/dist/interfaces/index.d.ts +3 -0
  33. package/dist/interfaces/index.js +20 -0
  34. package/dist/interfaces/index.js.map +1 -0
  35. package/dist/interfaces/kafka-module-options.interface.d.ts +43 -0
  36. package/dist/interfaces/kafka-module-options.interface.js +5 -0
  37. package/dist/interfaces/kafka-module-options.interface.js.map +1 -0
  38. package/dist/interfaces/message.interface.d.ts +26 -0
  39. package/dist/interfaces/message.interface.js +3 -0
  40. package/dist/interfaces/message.interface.js.map +1 -0
  41. package/dist/kafka.module.d.ts +7 -0
  42. package/dist/kafka.module.js +97 -0
  43. package/dist/kafka.module.js.map +1 -0
  44. package/dist/services/batch-processor.service.d.ts +16 -0
  45. package/dist/services/batch-processor.service.js +102 -0
  46. package/dist/services/batch-processor.service.js.map +1 -0
  47. package/dist/services/consumer-registry.service.d.ts +27 -0
  48. package/dist/services/consumer-registry.service.js +195 -0
  49. package/dist/services/consumer-registry.service.js.map +1 -0
  50. package/dist/services/dlq.service.d.ts +14 -0
  51. package/dist/services/dlq.service.js +90 -0
  52. package/dist/services/dlq.service.js.map +1 -0
  53. package/dist/services/idempotency.service.d.ts +16 -0
  54. package/dist/services/idempotency.service.js +76 -0
  55. package/dist/services/idempotency.service.js.map +1 -0
  56. package/dist/services/index.d.ts +7 -0
  57. package/dist/services/index.js +24 -0
  58. package/dist/services/index.js.map +1 -0
  59. package/dist/services/kafka-client.service.d.ts +31 -0
  60. package/dist/services/kafka-client.service.js +183 -0
  61. package/dist/services/kafka-client.service.js.map +1 -0
  62. package/dist/services/kafka-core.service.d.ts +13 -0
  63. package/dist/services/kafka-core.service.js +87 -0
  64. package/dist/services/kafka-core.service.js.map +1 -0
  65. package/dist/services/pressure-manager.service.d.ts +14 -0
  66. package/dist/services/pressure-manager.service.js +75 -0
  67. package/dist/services/pressure-manager.service.js.map +1 -0
  68. package/dist/tsconfig.build.tsbuildinfo +1 -0
  69. package/package.json +95 -0
@@ -0,0 +1,183 @@
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
+ var KafkaClient_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.KafkaClient = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const interfaces_1 = require("../interfaces");
19
+ const kafka_core_service_1 = require("./kafka-core.service");
20
+ let KafkaClient = KafkaClient_1 = class KafkaClient {
21
+ options;
22
+ kafkaCore;
23
+ logger = new common_1.Logger(KafkaClient_1.name);
24
+ producer;
25
+ isConnected = false;
26
+ batchBuffer = new Map();
27
+ batchTimer = null;
28
+ defaultBatchSize = 100;
29
+ defaultBatchTimeout = 100;
30
+ constructor(options, kafkaCore) {
31
+ this.options = options;
32
+ this.kafkaCore = kafkaCore;
33
+ }
34
+ async onModuleInit() {
35
+ this.producer = this.kafkaCore.getKafka().producer(this.options.producer);
36
+ await this.connect();
37
+ }
38
+ async onApplicationShutdown() {
39
+ await this.disconnect();
40
+ }
41
+ async connect() {
42
+ if (this.isConnected)
43
+ return;
44
+ try {
45
+ await this.producer.connect();
46
+ this.isConnected = true;
47
+ this.logger.log('Kafka producer connected');
48
+ }
49
+ catch (error) {
50
+ this.logger.error('Failed to connect Kafka producer', error);
51
+ throw error;
52
+ }
53
+ }
54
+ async disconnect() {
55
+ await this.flushAllBatches();
56
+ if (this.producer && this.isConnected) {
57
+ await this.producer.disconnect();
58
+ this.isConnected = false;
59
+ this.logger.log('Kafka producer disconnected');
60
+ }
61
+ }
62
+ async send(topic, message, options) {
63
+ const kafkaMessage = this.serializeMessage(message);
64
+ const record = {
65
+ topic,
66
+ messages: [kafkaMessage],
67
+ acks: options?.acks,
68
+ timeout: options?.timeout,
69
+ compression: options?.compression,
70
+ };
71
+ try {
72
+ await this.producer.send(record);
73
+ this.logger.debug(`Message sent to topic: ${topic}`);
74
+ }
75
+ catch (error) {
76
+ this.logger.error(`Failed to send message to topic: ${topic}`, error);
77
+ throw error;
78
+ }
79
+ }
80
+ async sendBatch(topic, messages, options) {
81
+ const kafkaMessages = messages.map((msg) => this.serializeMessage(msg));
82
+ const record = {
83
+ topic,
84
+ messages: kafkaMessages,
85
+ acks: options?.acks,
86
+ timeout: options?.timeout,
87
+ compression: options?.compression,
88
+ };
89
+ try {
90
+ await this.producer.send(record);
91
+ this.logger.debug(`Batch of ${messages.length} messages sent to topic: ${topic}`);
92
+ }
93
+ catch (error) {
94
+ this.logger.error(`Failed to send batch to topic: ${topic}`, error);
95
+ throw error;
96
+ }
97
+ }
98
+ async sendMultiTopicBatch(topicMessages, options) {
99
+ const batch = {
100
+ topicMessages: topicMessages.map(({ topic, messages }) => ({
101
+ topic,
102
+ messages: messages.map((msg) => this.serializeMessage(msg)),
103
+ })),
104
+ acks: options?.acks,
105
+ timeout: options?.timeout,
106
+ compression: options?.compression,
107
+ };
108
+ try {
109
+ await this.producer.sendBatch(batch);
110
+ this.logger.debug(`Multi-topic batch sent to ${topicMessages.length} topics`);
111
+ }
112
+ catch (error) {
113
+ this.logger.error('Failed to send multi-topic batch', error);
114
+ throw error;
115
+ }
116
+ }
117
+ async sendQueued(topic, message) {
118
+ const kafkaMessage = this.serializeMessage(message);
119
+ if (!this.batchBuffer.has(topic)) {
120
+ this.batchBuffer.set(topic, []);
121
+ }
122
+ this.batchBuffer.get(topic).push(kafkaMessage);
123
+ const buffer = this.batchBuffer.get(topic);
124
+ if (buffer.length >= this.defaultBatchSize) {
125
+ await this.flushBatch(topic);
126
+ }
127
+ else {
128
+ this.scheduleBatchFlush();
129
+ }
130
+ }
131
+ serializeMessage(message) {
132
+ let value;
133
+ if (message.value === null || message.value === undefined) {
134
+ value = null;
135
+ }
136
+ else if (typeof message.value === 'object') {
137
+ value = JSON.stringify(message.value);
138
+ }
139
+ else {
140
+ value = String(message.value);
141
+ }
142
+ return {
143
+ key: message.key ? String(message.key) : null,
144
+ value,
145
+ headers: message.headers,
146
+ partition: message.partition,
147
+ timestamp: message.timestamp,
148
+ };
149
+ }
150
+ scheduleBatchFlush() {
151
+ if (this.batchTimer)
152
+ return;
153
+ this.batchTimer = setTimeout(() => {
154
+ void this.flushAllBatches().then(() => {
155
+ this.batchTimer = null;
156
+ });
157
+ }, this.defaultBatchTimeout);
158
+ }
159
+ async flushBatch(topic) {
160
+ const messages = this.batchBuffer.get(topic);
161
+ if (!messages || messages.length === 0)
162
+ return;
163
+ this.batchBuffer.set(topic, []);
164
+ await this.producer.send({
165
+ topic,
166
+ messages,
167
+ });
168
+ }
169
+ async flushAllBatches() {
170
+ const topics = Array.from(this.batchBuffer.keys());
171
+ await Promise.all(topics.map((topic) => this.flushBatch(topic)));
172
+ }
173
+ isHealthy() {
174
+ return this.isConnected;
175
+ }
176
+ };
177
+ exports.KafkaClient = KafkaClient;
178
+ exports.KafkaClient = KafkaClient = KafkaClient_1 = __decorate([
179
+ (0, common_1.Injectable)(),
180
+ __param(0, (0, common_1.Inject)(interfaces_1.KAFKA_MODULE_OPTIONS)),
181
+ __metadata("design:paramtypes", [Object, kafka_core_service_1.KafkaCoreService])
182
+ ], KafkaClient);
183
+ //# sourceMappingURL=kafka-client.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kafka-client.service.js","sourceRoot":"","sources":["../../lib/services/kafka-client.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAMwB;AAExB,8CAKuB;AACvB,6DAAwD;AAGjD,IAAM,WAAW,mBAAjB,MAAM,WAAW;IAW2B;IAC9B;IAXF,MAAM,GAAG,IAAI,eAAM,CAAC,aAAW,CAAC,IAAI,CAAC,CAAC;IAC/C,QAAQ,CAAW;IACnB,WAAW,GAAG,KAAK,CAAC;IAEpB,WAAW,GAA2B,IAAI,GAAG,EAAE,CAAC;IAChD,UAAU,GAA0B,IAAI,CAAC;IAChC,gBAAgB,GAAG,GAAG,CAAC;IACvB,mBAAmB,GAAG,GAAG,CAAC;IAE3C,YACiD,OAA2B,EACzD,SAA2B;QADG,YAAO,GAAP,OAAO,CAAoB;QACzD,cAAS,GAAT,SAAS,CAAkB;IAC3C,CAAC;IAEJ,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1E,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,qBAAqB;QACzB,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAE7B,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACtC,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CACR,KAAa,EACb,OAAwB,EACxB,OAAqB;QAErB,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEpD,MAAM,MAAM,GAAmB;YAC7B,KAAK;YACL,QAAQ,EAAE,CAAC,YAAY,CAAC;YACxB,IAAI,EAAE,OAAO,EAAE,IAAI;YACnB,OAAO,EAAE,OAAO,EAAE,OAAO;YACzB,WAAW,EAAE,OAAO,EAAE,WAAW;SAClC,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;YACtE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CACb,KAAa,EACb,QAA2B,EAC3B,OAAqB;QAErB,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;QAExE,MAAM,MAAM,GAAmB;YAC7B,KAAK;YACL,QAAQ,EAAE,aAAa;YACvB,IAAI,EAAE,OAAO,EAAE,IAAI;YACnB,OAAO,EAAE,OAAO,EAAE,OAAO;YACzB,WAAW,EAAE,OAAO,EAAE,WAAW;SAClC,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,YAAY,QAAQ,CAAC,MAAM,4BAA4B,KAAK,EAAE,CAC/D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;YACpE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,aAAoE,EACpE,OAAqB;QAErB,MAAM,KAAK,GAAG;YACZ,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;gBACzD,KAAK;gBACL,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;aAC5D,CAAC,CAAC;YACH,IAAI,EAAE,OAAO,EAAE,IAAI;YACnB,OAAO,EAAE,OAAO,EAAE,OAAO;YACzB,WAAW,EAAE,OAAO,EAAE,WAAW;SAClC,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,6BAA6B,aAAa,CAAC,MAAM,SAAS,CAC3D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAa,EAAE,OAAwB;QACtD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEpD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;QAC5C,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3C,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,OAAwB;QAC/C,IAAI,KAA6B,CAAC;QAElC,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1D,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;aAAM,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC7C,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,OAAO;YACL,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;YAC7C,KAAK;YACL,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC;IACJ,CAAC;IAEO,kBAAkB;QACxB,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAE5B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;gBACpC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC/B,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,KAAa;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE/C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEhC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACvB,KAAK;YACL,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF,CAAA;AA7LY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;IAYR,WAAA,IAAA,eAAM,EAAC,iCAAoB,CAAC,CAAA;6CACD,qCAAgB;GAZnC,WAAW,CA6LvB"}
@@ -0,0 +1,13 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { Kafka } from 'kafkajs';
3
+ import { KafkaModuleOptions } from '../interfaces';
4
+ export declare class KafkaCoreService implements OnModuleInit {
5
+ private readonly options;
6
+ private readonly logger;
7
+ private kafka;
8
+ constructor(options: KafkaModuleOptions);
9
+ onModuleInit(): void;
10
+ getKafka(): Kafka;
11
+ getOptions(): KafkaModuleOptions;
12
+ private mapLogLevel;
13
+ }
@@ -0,0 +1,87 @@
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
+ var KafkaCoreService_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.KafkaCoreService = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const kafkajs_1 = require("kafkajs");
19
+ const interfaces_1 = require("../interfaces");
20
+ let KafkaCoreService = KafkaCoreService_1 = class KafkaCoreService {
21
+ options;
22
+ logger = new common_1.Logger(KafkaCoreService_1.name);
23
+ kafka;
24
+ constructor(options) {
25
+ this.options = options;
26
+ }
27
+ onModuleInit() {
28
+ this.kafka = new kafkajs_1.Kafka({
29
+ clientId: this.options.clientId,
30
+ brokers: this.options.brokers,
31
+ ssl: this.options.ssl,
32
+ sasl: this.options.sasl,
33
+ connectionTimeout: this.options.connectionTimeout,
34
+ requestTimeout: this.options.requestTimeout,
35
+ enforceRequestTimeout: this.options.enforceRequestTimeout,
36
+ retry: this.options.retry,
37
+ logLevel: this.mapLogLevel(this.options.logLevel),
38
+ logCreator: () => ({ level, log }) => {
39
+ const { message, ...extra } = log;
40
+ switch (level) {
41
+ case kafkajs_1.logLevel.ERROR:
42
+ this.logger.error(message, extra);
43
+ break;
44
+ case kafkajs_1.logLevel.WARN:
45
+ this.logger.warn(message, extra);
46
+ break;
47
+ case kafkajs_1.logLevel.INFO:
48
+ this.logger.log(message);
49
+ break;
50
+ case kafkajs_1.logLevel.DEBUG:
51
+ this.logger.debug(message);
52
+ break;
53
+ }
54
+ },
55
+ });
56
+ this.logger.log(`Kafka client initialized: ${this.options.clientId}`);
57
+ }
58
+ getKafka() {
59
+ return this.kafka;
60
+ }
61
+ getOptions() {
62
+ return this.options;
63
+ }
64
+ mapLogLevel(level) {
65
+ switch (level) {
66
+ case 'NOTHING':
67
+ return kafkajs_1.logLevel.NOTHING;
68
+ case 'ERROR':
69
+ return kafkajs_1.logLevel.ERROR;
70
+ case 'WARN':
71
+ return kafkajs_1.logLevel.WARN;
72
+ case 'INFO':
73
+ return kafkajs_1.logLevel.INFO;
74
+ case 'DEBUG':
75
+ return kafkajs_1.logLevel.DEBUG;
76
+ default:
77
+ return kafkajs_1.logLevel.INFO;
78
+ }
79
+ }
80
+ };
81
+ exports.KafkaCoreService = KafkaCoreService;
82
+ exports.KafkaCoreService = KafkaCoreService = KafkaCoreService_1 = __decorate([
83
+ (0, common_1.Injectable)(),
84
+ __param(0, (0, common_1.Inject)(interfaces_1.KAFKA_MODULE_OPTIONS)),
85
+ __metadata("design:paramtypes", [Object])
86
+ ], KafkaCoreService);
87
+ //# sourceMappingURL=kafka-core.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kafka-core.service.js","sourceRoot":"","sources":["../../lib/services/kafka-core.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA0E;AAC1E,qCAA0C;AAC1C,8CAAyE;AAGlE,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IAKsB;IAJhC,MAAM,GAAG,IAAI,eAAM,CAAC,kBAAgB,CAAC,IAAI,CAAC,CAAC;IACpD,KAAK,CAAQ;IAErB,YACiD,OAA2B;QAA3B,YAAO,GAAP,OAAO,CAAoB;IACzE,CAAC;IAEJ,YAAY;QACV,IAAI,CAAC,KAAK,GAAG,IAAI,eAAK,CAAC;YACrB,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;YAC/B,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAmB;YACzC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;YACrB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YACvB,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB;YACjD,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC3C,qBAAqB,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB;YACzD,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;YACzB,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACjD,UAAU,EACR,GAAG,EAAE,CACL,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE;gBACjB,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,GAAG,CAAC;gBAClC,QAAQ,KAAK,EAAE,CAAC;oBACd,KAAK,kBAAQ,CAAC,KAAK;wBACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;wBAClC,MAAM;oBACR,KAAK,kBAAQ,CAAC,IAAI;wBAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;wBACjC,MAAM;oBACR,KAAK,kBAAQ,CAAC,IAAI;wBAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBACzB,MAAM;oBACR,KAAK,kBAAQ,CAAC,KAAK;wBACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBAC3B,MAAM;gBACV,CAAC;YACH,CAAC;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAEO,WAAW,CAAC,KAAc;QAChC,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,SAAS;gBACZ,OAAO,kBAAQ,CAAC,OAAO,CAAC;YAC1B,KAAK,OAAO;gBACV,OAAO,kBAAQ,CAAC,KAAK,CAAC;YACxB,KAAK,MAAM;gBACT,OAAO,kBAAQ,CAAC,IAAI,CAAC;YACvB,KAAK,MAAM;gBACT,OAAO,kBAAQ,CAAC,IAAI,CAAC;YACvB,KAAK,OAAO;gBACV,OAAO,kBAAQ,CAAC,KAAK,CAAC;YACxB;gBACE,OAAO,kBAAQ,CAAC,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;CACF,CAAA;AAnEY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;IAMR,WAAA,IAAA,eAAM,EAAC,iCAAoB,CAAC,CAAA;;GALpB,gBAAgB,CAmE5B"}
@@ -0,0 +1,14 @@
1
+ import { Consumer } from 'kafkajs';
2
+ import { PressureState, PressureManagerOptions } from '../interfaces';
3
+ export declare class PressureManagerService {
4
+ private readonly logger;
5
+ private states;
6
+ private consumers;
7
+ private options;
8
+ register(consumerId: string, consumer: Consumer, opts: PressureManagerOptions): void;
9
+ updateQueueSize(consumerId: string, size: number): void;
10
+ updateConcurrency(consumerId: string, delta: number): void;
11
+ private checkPressure;
12
+ getState(consumerId: string): PressureState | undefined;
13
+ isPaused(consumerId: string): boolean;
14
+ }
@@ -0,0 +1,75 @@
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 PressureManagerService_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.PressureManagerService = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ let PressureManagerService = PressureManagerService_1 = class PressureManagerService {
13
+ logger = new common_1.Logger(PressureManagerService_1.name);
14
+ states = new Map();
15
+ consumers = new Map();
16
+ options = new Map();
17
+ register(consumerId, consumer, opts) {
18
+ this.consumers.set(consumerId, consumer);
19
+ this.options.set(consumerId, opts);
20
+ this.states.set(consumerId, {
21
+ isPaused: false,
22
+ currentQueueSize: 0,
23
+ maxQueueSize: opts.maxQueueSize,
24
+ currentConcurrency: 0,
25
+ maxConcurrency: opts.backPressureThreshold,
26
+ utilizationPercent: 0,
27
+ });
28
+ }
29
+ updateQueueSize(consumerId, size) {
30
+ const state = this.states.get(consumerId);
31
+ const opts = this.options.get(consumerId);
32
+ if (!state || !opts)
33
+ return;
34
+ state.currentQueueSize = size;
35
+ state.utilizationPercent = (size / state.maxQueueSize) * 100;
36
+ this.checkPressure(consumerId);
37
+ }
38
+ updateConcurrency(consumerId, delta) {
39
+ const state = this.states.get(consumerId);
40
+ if (!state)
41
+ return;
42
+ state.currentConcurrency += delta;
43
+ this.checkPressure(consumerId);
44
+ }
45
+ checkPressure(consumerId) {
46
+ const state = this.states.get(consumerId);
47
+ const consumer = this.consumers.get(consumerId);
48
+ const opts = this.options.get(consumerId);
49
+ if (!state || !consumer || !opts)
50
+ return;
51
+ const shouldPause = state.utilizationPercent >= opts.backPressureThreshold;
52
+ const shouldResume = state.utilizationPercent <= opts.resumeThreshold;
53
+ if (shouldPause && !state.isPaused) {
54
+ this.logger.warn(`Back pressure triggered for ${consumerId}, pausing consumer`);
55
+ consumer.pause([{ topic: '*' }]);
56
+ state.isPaused = true;
57
+ }
58
+ else if (shouldResume && state.isPaused) {
59
+ this.logger.log(`Resuming consumer ${consumerId}`);
60
+ consumer.resume([{ topic: '*' }]);
61
+ state.isPaused = false;
62
+ }
63
+ }
64
+ getState(consumerId) {
65
+ return this.states.get(consumerId);
66
+ }
67
+ isPaused(consumerId) {
68
+ return this.states.get(consumerId)?.isPaused ?? false;
69
+ }
70
+ };
71
+ exports.PressureManagerService = PressureManagerService;
72
+ exports.PressureManagerService = PressureManagerService = PressureManagerService_1 = __decorate([
73
+ (0, common_1.Injectable)()
74
+ ], PressureManagerService);
75
+ //# sourceMappingURL=pressure-manager.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pressure-manager.service.js","sourceRoot":"","sources":["../../lib/services/pressure-manager.service.ts"],"names":[],"mappings":"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"}