@kaapi/kafka-messaging 0.0.13 → 0.0.15

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 CHANGED
@@ -1,3 +1,248 @@
1
- # @kaapi/kafka-messaging
1
+ # 📦 @kaapi/kafka-messaging
2
2
 
3
- Kafka-based messaging for kaapi.
3
+ `@kaapi/kafka-messaging` is a lightweight wrapper around [`kafkajs`](https://github.com/tulios/kafkajs) that integrates with the [`Kaapi`](https://github.com/demingongo/kaapi) framework to provide a clean and consistent **message publishing and consuming interface**.
4
+
5
+ It abstracts Kafka’s producer/consumer logic and provides a simple interface to:
6
+
7
+ * ✅ Publish messages
8
+ * ✅ Subscribe to topics
9
+ * ✅ Support structured logging via Kaapi's logger
10
+ * ✅ Handle offsets and message metadata
11
+ * ✅ Reuse Kafka producers/consumers
12
+
13
+ ---
14
+
15
+ ## ✨ Features
16
+
17
+ * Simple `publish(topic, message)` API
18
+ * Flexible `subscribe(topic, handler, config)` with offset tracking
19
+ * KafkaJS-compatible configuration
20
+ * Structured logging via Kaapi’s `ILogger`
21
+ * Typed message handling with TypeScript
22
+
23
+ ---
24
+
25
+ ## 🚀 Getting Started with KafkaMessaging
26
+
27
+ This guide walks you through setting up and using the `KafkaMessaging` class to publish and consume messages with Apache Kafka.
28
+
29
+ ### Installation
30
+
31
+ ```bash
32
+ npm install @kaapi/kafka-messaging kafkajs
33
+ ```
34
+
35
+ ---
36
+
37
+ ### Basic Setup
38
+
39
+ ```ts
40
+ import { KafkaMessaging } from '@kaapi/kafka-messaging';
41
+
42
+ const messaging = new KafkaMessaging({
43
+ clientId: 'my-app',
44
+ brokers: ['localhost:9092'],
45
+ name: 'my-service',
46
+ address: 'service-1',
47
+ logger: createLogger() // optional, use Kaapi ILogger
48
+ });
49
+ ```
50
+
51
+ The constructor accepts a `KafkaMessagingConfig` object, which extends `KafkaConfig` from [kafkajs](https://kafka.js.org/):
52
+
53
+ | Option | Type | Description |
54
+ | ---------- | ---------------- | ------------------------------------------------------------------------- |
55
+ | `brokers` | `string[]` | List of Kafka broker addresses (e.g. `['localhost:9092']`). **Required.** |
56
+ | `clientId` | `string` | Unique client identifier for Kafka. |
57
+ | `logger` | `ILogger` | Optional logger implementing Kaapi's `ILogger` interface. |
58
+ | `address` | `string` | Optional unique service address for routing and identification. |
59
+ | `name` | `string` | Optional human-readable name for service tracking/monitoring. |
60
+ | `producer` | `ProducerConfig` | Optional default KafkaJS producer configuration. |
61
+
62
+ ---
63
+
64
+ ### Creating a Topic
65
+
66
+ ```ts
67
+ await messaging.createTopic({
68
+ topic: 'my-topic',
69
+ numPartitions: 1,
70
+ replicationFactor: 1,
71
+ }, {
72
+ waitForLeaders: true
73
+ });
74
+
75
+ // ensure the topic is ready before publishing
76
+ const timeoutMs = 10000;
77
+ const checkIntervalMs = 200;
78
+ await messaging.waitForTopicReady('my-topic', timeoutMs, checkIntervalMs);
79
+ ```
80
+
81
+ ---
82
+
83
+ ### Publishing a Message
84
+
85
+ `publish(topic, message)` sends a message to a given Kafka topic.
86
+
87
+ ```ts
88
+ await messaging.publish('my-topic', {
89
+ userId: '123',
90
+ action: 'login',
91
+ });
92
+ ```
93
+
94
+ * `topic`: The Kafka topic name
95
+ * `message`: Any serializable object
96
+
97
+ ---
98
+
99
+ ### Subscribing to a Topic
100
+
101
+ `subscribe(topic, handler, config?)` subscribes to a Kafka topic and calls the provided handler on each message.
102
+
103
+ ```ts
104
+ await messaging.subscribe('my-topic', async (message, sender) => {
105
+ console.log('Received:', message);
106
+ console.log('From:', sender.name, sender.address);
107
+ console.log('Offset:', sender.offset);
108
+ }, {
109
+ fromBeginning: true
110
+ });
111
+ ```
112
+
113
+ * `topic`: The Kafka topic name
114
+ * `handler`: `(message, sender) => void | Promise<void>`
115
+ * `config?`: `KafkaMessagingSubscribeConfig` (extends `ConsumerConfig`)
116
+ * `groupId?`: Kafka consumer group ID
117
+ * `fromBeginning?`: boolean - Start consuming from beginning of topic
118
+
119
+ ---
120
+
121
+ ### Graceful Shutdown
122
+
123
+ ```ts
124
+ await messaging.shutdown();
125
+ ```
126
+ This will disconnect all tracked producers, consumers, and admin clients safely.
127
+
128
+ ---
129
+
130
+ ## 🧱 Example Usage
131
+
132
+ ```ts
133
+ // messaging.ts
134
+
135
+ import { Kaapi, createLogger } from '@kaapi/kaapi'
136
+ import { KafkaMessaging } from '@kaapi/kafka-messaging';
137
+
138
+ const messaging = new KafkaMessaging({
139
+ clientId: 'my-app',
140
+ brokers: ['localhost:9092'],
141
+ name: 'my-service',
142
+ address: 'service-1'
143
+ });
144
+
145
+ /**
146
+ * Initialize the Kaapi app with messaging
147
+ */
148
+ const app = new Kaapi({
149
+ port: 3000,
150
+ host: 'localhost',
151
+ messaging,
152
+ });
153
+
154
+ /**
155
+ * Demonstrates how to subscribe and publish a message
156
+ */
157
+ async function runExample(): Promise<void> {
158
+
159
+ /**
160
+ * Option 1: Use Kaapi app (recommended in app lifecycle)
161
+ */
162
+ // Publish a message
163
+ await app.publish('my-topic', { event: 'user.created', userId: 456 });
164
+
165
+ // Subscribe to messages
166
+ await app.subscribe('my-topic', async (message, sender) => {
167
+ console.log('Received:', message);
168
+ console.log('Offset:', sender.offset);
169
+ });
170
+
171
+ /**
172
+ * Option 2: Use messaging directly (standalone)
173
+ */
174
+ // Publish a message
175
+ await messaging.publish('my-topic', { event: 'user.created', userId: 123 });
176
+
177
+ // Subscribe to messages
178
+ await messaging.subscribe('my-topic', async (message, sender) => {
179
+ console.log('Received:', message);
180
+ console.log('Offset:', sender.offset);
181
+ });
182
+ }
183
+
184
+ runExample().catch((err) => {
185
+ console.error('❌ Messaging example failed:', err);
186
+ });
187
+ ```
188
+
189
+ ---
190
+
191
+ ## Public API Contract
192
+
193
+ The `KafkaMessaging` class provides a safe and resilient interface for interacting with Kafka. Developers should use the following methods to ensure proper lifecycle management, resource tracking, and graceful shutdown.
194
+
195
+ ### Public Methods
196
+
197
+ | Method | Purpose |
198
+ |-----------------------------------|-------------------------------------------------------------------------|
199
+ | `createProducer()` | Creates and connects a Kafka producer. Automatically tracked and cleaned up. |
200
+ | `createConsumer(groupId, config?)`| Creates and connects a Kafka consumer. Automatically tracked and cleaned up. |
201
+ | `createAdmin(config?)` | Creates and connects a Kafka admin client. Tracked for shutdown. |
202
+ | `publish(topic, message)` | Sends a message to the specified topic using the managed producer. |
203
+ | `subscribe(topic, handler, config?)` | Subscribes to a topic and processes messages with the given handler. |
204
+ | `shutdown()` | Gracefully disconnects all tracked producers, consumers, and admins. |
205
+ | `safeDisconnect(client, timeoutMs?)` | Disconnects a Kafka client with timeout protection. |
206
+ | `createTopic(topicConfig, options?)` | Creates a Kafka topic with optional validation and leader wait. |
207
+ | `waitForTopicReady(topic, timeoutMs?, checkIntervalMs?)` | Ensures the topic is ready. |
208
+
209
+ ### Internal Methods (Not Public)
210
+
211
+ | Method | Status | Reason for Restriction |
212
+ |----------------|------------|-------------------------------------------------|
213
+ | `getKafka()` | Protected | Used internally to instantiate Kafka clients. Avoid direct access to prevent unmanaged connections. |
214
+
215
+ ### Best Practices
216
+
217
+ - Always use `createProducer`, `createConsumer`, or `createAdmin` to ensure proper tracking.
218
+ - Avoid accessing the raw Kafka instance directly.
219
+ - Call `shutdown()` during application teardown to release resources.
220
+ - Use `createTopic()` and `waitForTopicReady()` in tests or dynamic topic scenarios.
221
+
222
+ ---
223
+
224
+ ## 🛠️ Requirements
225
+
226
+ * Node.js 16+
227
+ * A running Kafka instance
228
+ * Optional: integrate into a [Kaapi](https://github.com/demingongo/kaapi) service lifecycle
229
+
230
+ ---
231
+
232
+ ## 📚 Related
233
+
234
+ * [KafkaJS](https://github.com/tulios/kafkajs) — the underlying Kafka client
235
+ * [Kaapi](https://github.com/demingongo/kaapi) — framework powering this abstraction
236
+ * [@kaapi/kaapi](https://www.npmjs.com/package/@kaapi/kaapi)
237
+
238
+ ---
239
+
240
+ ## 🧪 Testing
241
+
242
+ You can mock Kafka in tests or point to a local dev broker. Integration testing can be done using Docker or services like Redpanda.
243
+
244
+ ---
245
+
246
+ ## 📝 License
247
+
248
+ MIT
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Consumer, ConsumerConfig, Kafka, KafkaConfig, Producer } from 'kafkajs';
1
+ import { Admin, AdminConfig, Consumer, ConsumerConfig, ITopicConfig, Kafka, KafkaConfig, Producer, ProducerConfig } from 'kafkajs';
2
2
  import { ILogger, IMessaging, IMessagingSender } from '@kaapi/kaapi';
3
3
  export interface KafkaMessagingSender extends IMessagingSender {
4
4
  offset?: string;
@@ -7,24 +7,76 @@ export interface KafkaMessagingConfig extends KafkaConfig {
7
7
  logger?: ILogger;
8
8
  address?: string;
9
9
  name?: string;
10
+ producer?: ProducerConfig;
10
11
  }
11
12
  export interface KafkaMessagingSubscribeConfig extends Partial<ConsumerConfig> {
12
13
  fromBeginning?: boolean;
14
+ onReady?(consumer: Consumer): void;
13
15
  }
14
16
  export declare class KafkaMessaging implements IMessaging {
15
17
  #private;
16
18
  protected kafka?: Kafka;
17
19
  protected logger?: ILogger;
18
20
  protected producer?: Producer;
21
+ protected currentProducerId?: string;
22
+ get activeConsumers(): ReadonlySet<Consumer>;
23
+ get activeProducers(): ReadonlySet<Producer>;
19
24
  constructor(arg: KafkaMessagingConfig);
20
25
  private _createInstance;
21
- protected getAdmin(): Promise<import("kafkajs").Admin | undefined>;
22
- getKafka(): Kafka | undefined;
23
- getConsumer(topic: string, config?: Partial<ConsumerConfig>): Promise<Consumer | undefined>;
26
+ protected getKafka(): Kafka | undefined;
27
+ createAdmin(config?: AdminConfig): Promise<Admin | undefined>;
28
+ createTopic(topic: ITopicConfig, config?: {
29
+ validateOnly?: boolean;
30
+ waitForLeaders?: boolean;
31
+ timeout?: number;
32
+ }): Promise<void>;
33
+ /**
34
+ * Waits for a Kafka topic to become ready (i.e., it exists and has partitions).
35
+ *
36
+ * @param {string} topic - The name of the Kafka topic to check.
37
+ * @param {number} [timeoutMs=10000] - Maximum time (in milliseconds) to wait for the topic to be ready.
38
+ * @param {number} [checkIntervalMs=200] - Interval (in milliseconds) between readiness checks. Must be ≥ 200ms.
39
+ *
40
+ * @throws {Error} If `checkIntervalMs` is less than 200ms.
41
+ * @throws {Error} If `timeoutMs` is less than or equal to `checkIntervalMs`.
42
+ * @throws {Error} If the admin client cannot be created.
43
+ * @throws {Error} If the topic is not ready within the given timeout.
44
+ *
45
+ * @returns {Promise<void>} Resolves when the topic is ready.
46
+ */
47
+ waitForTopicReady(topic: string, timeoutMs?: number, checkIntervalMs?: number): Promise<void>;
48
+ /**
49
+ * Create a new consumer with optional configuration overrides
50
+ * @param groupId Consumer group id
51
+ * @param config Consumer configuration overrides
52
+ * @returns
53
+ */
54
+ createConsumer(groupId: string, config?: Partial<ConsumerConfig>): Promise<Consumer | undefined>;
55
+ /**
56
+ * Create a new producer with optional configuration overrides
57
+ * @param config Producer configuration overrides
58
+ * @returns
59
+ */
60
+ createProducer(config?: Partial<ProducerConfig>): Promise<Producer | undefined>;
61
+ /**
62
+ * Get the producer
63
+ */
24
64
  getProducer(): Promise<Producer | undefined>;
65
+ /**
66
+ * Disconnect the producer
67
+ */
68
+ disconnectProducer(): Promise<void>;
25
69
  publish<T = unknown>(topic: string, message: T): Promise<void>;
26
70
  /**
27
71
  * Listen to a topic
28
72
  */
29
- subscribe<T = unknown>(topic: string, handler: (message: T, sender: KafkaMessagingSender) => Promise<void> | void, conf?: KafkaMessagingSubscribeConfig): Promise<void>;
73
+ subscribe<T = unknown>(topic: string, handler: (message: T, sender: KafkaMessagingSender) => Promise<void> | void, config?: KafkaMessagingSubscribeConfig): Promise<void>;
74
+ safeDisconnect(client: Producer | Consumer | Admin, timeoutMs?: number): Promise<unknown>;
75
+ shutdown(): Promise<{
76
+ successProducers: number;
77
+ successConsumers: number;
78
+ successAdmins: number;
79
+ errorCount: number;
80
+ }>;
30
81
  }
82
+ export declare function safeDisconnect(client: Producer | Consumer | Admin, timeoutMs?: number): Promise<unknown>;
package/lib/index.js CHANGED
@@ -1,16 +1,29 @@
1
1
  "use strict";
2
- var _KafkaMessaging_config, _KafkaMessaging_address, _KafkaMessaging_name;
2
+ var _KafkaMessaging_config, _KafkaMessaging_producerConfig, _KafkaMessaging_address, _KafkaMessaging_name, _KafkaMessaging_consumers, _KafkaMessaging_producers, _KafkaMessaging_admins;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.KafkaMessaging = void 0;
5
+ exports.safeDisconnect = safeDisconnect;
5
6
  const tslib_1 = require("tslib");
6
7
  const kafkajs_1 = require("kafkajs");
8
+ const crypto_1 = require("crypto");
7
9
  class KafkaMessaging {
10
+ get activeConsumers() {
11
+ return tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_consumers, "f");
12
+ }
13
+ get activeProducers() {
14
+ return tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_producers, "f");
15
+ }
8
16
  constructor(arg) {
9
17
  _KafkaMessaging_config.set(this, void 0);
18
+ _KafkaMessaging_producerConfig.set(this, void 0);
10
19
  _KafkaMessaging_address.set(this, void 0);
11
20
  _KafkaMessaging_name.set(this, void 0);
12
- const { logger, address, name } = arg, kafkaConfig = tslib_1.__rest(arg, ["logger", "address", "name"]);
21
+ _KafkaMessaging_consumers.set(this, new Set());
22
+ _KafkaMessaging_producers.set(this, new Set());
23
+ _KafkaMessaging_admins.set(this, new Set());
24
+ const { logger, address, name, producer } = arg, kafkaConfig = tslib_1.__rest(arg, ["logger", "address", "name", "producer"]);
13
25
  tslib_1.__classPrivateFieldSet(this, _KafkaMessaging_config, kafkaConfig, "f");
26
+ tslib_1.__classPrivateFieldSet(this, _KafkaMessaging_producerConfig, producer, "f");
14
27
  tslib_1.__classPrivateFieldSet(this, _KafkaMessaging_name, name, "f");
15
28
  tslib_1.__classPrivateFieldSet(this, _KafkaMessaging_address, address, "f");
16
29
  this.logger = logger;
@@ -44,26 +57,83 @@ class KafkaMessaging {
44
57
  }
45
58
  } }, tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_config, "f")));
46
59
  }
47
- getAdmin() {
60
+ getKafka() {
61
+ if (!this.kafka) {
62
+ this.kafka = this._createInstance();
63
+ }
64
+ return this.kafka;
65
+ }
66
+ createAdmin(config) {
48
67
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
49
68
  // Get kafka instance
50
69
  const kafka = this.getKafka();
51
70
  // If we don't have a connection, abort
52
71
  if (!kafka)
53
72
  return;
54
- const admin = kafka.admin();
73
+ const admin = kafka.admin(config);
55
74
  yield admin.connect();
75
+ tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_admins, "f").add(admin);
76
+ admin.on(admin.events.DISCONNECT, () => {
77
+ tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_admins, "f").delete(admin);
78
+ });
56
79
  return admin;
57
80
  });
58
81
  }
59
- getKafka() {
60
- if (!this.kafka) {
61
- this.kafka = this._createInstance();
62
- }
63
- return this.kafka;
82
+ createTopic(topic, config) {
83
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
84
+ const admin = yield this.createAdmin();
85
+ if (!admin)
86
+ throw new Error('Admin client unavailable');
87
+ yield admin.createTopics(Object.assign({ topics: [topic] }, (config || {})));
88
+ yield admin.disconnect();
89
+ });
64
90
  }
65
- // Get the consumer
66
- getConsumer(topic, config) {
91
+ /**
92
+ * Waits for a Kafka topic to become ready (i.e., it exists and has partitions).
93
+ *
94
+ * @param {string} topic - The name of the Kafka topic to check.
95
+ * @param {number} [timeoutMs=10000] - Maximum time (in milliseconds) to wait for the topic to be ready.
96
+ * @param {number} [checkIntervalMs=200] - Interval (in milliseconds) between readiness checks. Must be ≥ 200ms.
97
+ *
98
+ * @throws {Error} If `checkIntervalMs` is less than 200ms.
99
+ * @throws {Error} If `timeoutMs` is less than or equal to `checkIntervalMs`.
100
+ * @throws {Error} If the admin client cannot be created.
101
+ * @throws {Error} If the topic is not ready within the given timeout.
102
+ *
103
+ * @returns {Promise<void>} Resolves when the topic is ready.
104
+ */
105
+ waitForTopicReady(topic_1) {
106
+ return tslib_1.__awaiter(this, arguments, void 0, function* (topic, timeoutMs = 10000, checkIntervalMs = 200) {
107
+ if (checkIntervalMs < 200) {
108
+ throw new Error(`Invalid checkIntervalMs: ${checkIntervalMs}. It must be at least 200ms to avoid overwhelming the broker.`);
109
+ }
110
+ if (timeoutMs <= checkIntervalMs) {
111
+ throw new Error(`Invalid configuration: timeoutMs (${timeoutMs}) must be greater than checkIntervalMs (${checkIntervalMs}).`);
112
+ }
113
+ const start = Date.now();
114
+ const admin = yield this.createAdmin();
115
+ if (!admin)
116
+ throw new Error('Admin client unavailable');
117
+ while (Date.now() - start < timeoutMs) {
118
+ const metadata = yield admin.fetchTopicMetadata({ topics: [topic] });
119
+ const topicMeta = metadata.topics.find(t => t.name === topic);
120
+ if (topicMeta && topicMeta.partitions.length > 0) {
121
+ yield admin.disconnect();
122
+ return;
123
+ }
124
+ yield new Promise(res => setTimeout(res, checkIntervalMs)); // wait 200ms before retry
125
+ }
126
+ yield admin.disconnect();
127
+ throw new Error(`Timeout: Topic "${topic}" did not become ready within ${timeoutMs}ms.`);
128
+ });
129
+ }
130
+ /**
131
+ * Create a new consumer with optional configuration overrides
132
+ * @param groupId Consumer group id
133
+ * @param config Consumer configuration overrides
134
+ * @returns
135
+ */
136
+ createConsumer(groupId, config) {
67
137
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
68
138
  // Get kafka instance
69
139
  const kafka = this.getKafka();
@@ -71,7 +141,7 @@ class KafkaMessaging {
71
141
  if (!kafka)
72
142
  return;
73
143
  let overridenConfig = {
74
- groupId: `${tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_name, "f") || 'group'}---${topic}`,
144
+ groupId: `${groupId}`,
75
145
  readUncommitted: true
76
146
  };
77
147
  if (config && typeof config == 'object') {
@@ -79,27 +149,86 @@ class KafkaMessaging {
79
149
  }
80
150
  const consumer = kafka.consumer(overridenConfig);
81
151
  yield consumer.connect();
152
+ // track consumers to disconnect them later
153
+ tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_consumers, "f").add(consumer);
154
+ consumer.on(consumer.events.DISCONNECT, () => {
155
+ tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_consumers, "f").delete(consumer);
156
+ });
82
157
  return consumer;
83
158
  });
84
159
  }
85
- // Get the producer
160
+ /**
161
+ * Create a new producer with optional configuration overrides
162
+ * @param config Producer configuration overrides
163
+ * @returns
164
+ */
165
+ createProducer(config) {
166
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
167
+ // Get kafka instance
168
+ const kafka = this.getKafka();
169
+ // If we don't have an instance, abort
170
+ if (!kafka)
171
+ return;
172
+ let overridenConfig = {
173
+ /*
174
+ idempotent: true,
175
+ retry: {
176
+ retries: 5,
177
+ initialRetryTime: 300,
178
+ }
179
+ */
180
+ };
181
+ if (config && typeof config == 'object') {
182
+ overridenConfig = Object.assign(Object.assign({}, overridenConfig), config);
183
+ }
184
+ const producer = kafka.producer(overridenConfig);
185
+ yield producer.connect();
186
+ // track producers to disconnect them later
187
+ tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_producers, "f").add(producer);
188
+ producer.on(producer.events.DISCONNECT, () => {
189
+ tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_producers, "f").delete(producer);
190
+ });
191
+ return producer;
192
+ });
193
+ }
194
+ /**
195
+ * Get the producer
196
+ */
86
197
  getProducer() {
87
198
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
88
199
  var _a;
89
200
  if (!this.producer) {
90
- // Get kafka instance
91
- const kafka = this.getKafka();
92
- // If we don't have an instance, abort
93
- if (!kafka)
201
+ const producer = yield this.createProducer(tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_producerConfig, "f"));
202
+ if (!producer)
94
203
  return;
95
- const producer = kafka.producer();
96
- yield producer.connect();
204
+ const producerId = (0, crypto_1.randomBytes)(16).toString('hex');
97
205
  this.producer = producer;
206
+ this.currentProducerId = producerId;
98
207
  (_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug('✔️ Producer connected');
208
+ producer.on(producer.events.DISCONNECT, () => {
209
+ var _a;
210
+ if (this.currentProducerId === producerId) {
211
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('⚠️ Producer disconnected');
212
+ this.producer = undefined;
213
+ this.currentProducerId = undefined;
214
+ }
215
+ });
99
216
  }
100
217
  return this.producer;
101
218
  });
102
219
  }
220
+ /**
221
+ * Disconnect the producer
222
+ */
223
+ disconnectProducer() {
224
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
225
+ if (this.producer) {
226
+ yield this.producer.disconnect();
227
+ this.producer = undefined;
228
+ this.currentProducerId = undefined;
229
+ }
230
+ });
231
+ }
103
232
  publish(topic, message) {
104
233
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
105
234
  var _a, _b;
@@ -130,19 +259,21 @@ class KafkaMessaging {
130
259
  /**
131
260
  * Listen to a topic
132
261
  */
133
- subscribe(topic, handler, conf) {
262
+ subscribe(topic, handler, config) {
134
263
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
135
264
  var _a, _b, _c;
136
265
  (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`👂 Subscribing KAFKA topic "${topic}"`);
137
266
  let consumerConfig;
138
267
  let fromBeginning;
139
- if (conf) {
140
- const { fromBeginning: tmpFromBeginning } = conf, tmpConsumerConfig = tslib_1.__rest(conf, ["fromBeginning"]);
268
+ let onReady;
269
+ if (config) {
270
+ const { fromBeginning: tmpFromBeginning, onReady: tmpOnReady } = config, tmpConsumerConfig = tslib_1.__rest(config, ["fromBeginning", "onReady"]);
141
271
  fromBeginning = tmpFromBeginning;
272
+ onReady = tmpOnReady;
142
273
  consumerConfig = tmpConsumerConfig;
143
274
  }
144
275
  // Get kafka consumer
145
- const consumer = yield this.getConsumer(topic, consumerConfig);
276
+ const consumer = yield this.createConsumer(`${tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_name, "f") || 'group'}---${topic}`, consumerConfig);
146
277
  // If we don't have a consumer, abort
147
278
  if (!consumer)
148
279
  return (_b = this.logger) === null || _b === void 0 ? void 0 : _b.error('❌ Could not get consumer');
@@ -151,7 +282,7 @@ class KafkaMessaging {
151
282
  topic,
152
283
  fromBeginning
153
284
  });
154
- const admin = yield this.getAdmin();
285
+ const admin = yield this.createAdmin();
155
286
  if (admin) {
156
287
  try {
157
288
  const partitions = yield admin.fetchTopicOffsets(topic);
@@ -202,9 +333,73 @@ class KafkaMessaging {
202
333
  }
203
334
  }),
204
335
  });
336
+ onReady === null || onReady === void 0 ? void 0 : onReady(consumer);
337
+ });
338
+ }
339
+ safeDisconnect(client_1) {
340
+ return tslib_1.__awaiter(this, arguments, void 0, function* (client, timeoutMs = 5000) {
341
+ return safeDisconnect(client, timeoutMs);
342
+ });
343
+ }
344
+ shutdown() {
345
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
346
+ var _a, _b, _c, _d, _e, _f;
347
+ let errorCount = 0;
348
+ let successProducers = 0;
349
+ let successConsumers = 0;
350
+ let successAdmins = 0;
351
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info('🛑 Shutting down KafkaMessaging...');
352
+ for (const producer of tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_producers, "f")) {
353
+ try {
354
+ yield this.safeDisconnect(producer);
355
+ successProducers++;
356
+ }
357
+ catch (e) {
358
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.error('Error disconnecting producer:', e);
359
+ errorCount++;
360
+ }
361
+ }
362
+ for (const consumer of tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_consumers, "f")) {
363
+ try {
364
+ yield consumer.stop(); // Gracefully stop consuming
365
+ yield this.safeDisconnect(consumer);
366
+ successConsumers++;
367
+ }
368
+ catch (e) {
369
+ (_c = this.logger) === null || _c === void 0 ? void 0 : _c.error('Error disconnecting consumer:', e);
370
+ errorCount++;
371
+ }
372
+ }
373
+ for (const admin of tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_admins, "f")) {
374
+ try {
375
+ yield this.safeDisconnect(admin);
376
+ tslib_1.__classPrivateFieldGet(this, _KafkaMessaging_admins, "f").delete(admin);
377
+ successAdmins++;
378
+ }
379
+ catch (e) {
380
+ (_d = this.logger) === null || _d === void 0 ? void 0 : _d.error('Error disconnecting admin:', e);
381
+ errorCount++;
382
+ }
383
+ }
384
+ (_e = this.logger) === null || _e === void 0 ? void 0 : _e.info('KafkaMessaging shutdown complete');
385
+ (_f = this.logger) === null || _f === void 0 ? void 0 : _f.info(`Disconnected ${successProducers} producers, ${successConsumers} consumers and ${successAdmins} admins with ${errorCount} errors.`);
386
+ return {
387
+ successProducers,
388
+ successConsumers,
389
+ successAdmins,
390
+ errorCount,
391
+ };
205
392
  });
206
393
  }
207
394
  }
208
395
  exports.KafkaMessaging = KafkaMessaging;
209
- _KafkaMessaging_config = new WeakMap(), _KafkaMessaging_address = new WeakMap(), _KafkaMessaging_name = new WeakMap();
396
+ _KafkaMessaging_config = new WeakMap(), _KafkaMessaging_producerConfig = new WeakMap(), _KafkaMessaging_address = new WeakMap(), _KafkaMessaging_name = new WeakMap(), _KafkaMessaging_consumers = new WeakMap(), _KafkaMessaging_producers = new WeakMap(), _KafkaMessaging_admins = new WeakMap();
397
+ function safeDisconnect(client_1) {
398
+ return tslib_1.__awaiter(this, arguments, void 0, function* (client, timeoutMs = 5000) {
399
+ return Promise.race([
400
+ client.disconnect(),
401
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Disconnect timed out')), timeoutMs)),
402
+ ]);
403
+ });
404
+ }
210
405
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaapi/kafka-messaging",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "private": false,
5
5
  "description": "Kafka-based messaging for kaapi",
6
6
  "main": "lib/index.js",
@@ -14,7 +14,10 @@
14
14
  "dependencies": {
15
15
  "kafkajs": "^2.2.4",
16
16
  "tslib": "^2.8.1",
17
- "@kaapi/kaapi": "^0.0.13"
17
+ "@kaapi/kaapi": "^0.0.15"
18
+ },
19
+ "devDependencies": {
20
+ "@types/mocha": "^10.0.10"
18
21
  },
19
22
  "scripts": {
20
23
  "lint": "eslint .",
@@ -0,0 +1,129 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
2
+
3
+ // test/kafka-messaging.spec.ts
4
+
5
+ import { expect } from 'chai';
6
+ import { KafkaMessaging } from '../src/index';
7
+
8
+ describe('KafkaMessaging', () => {
9
+ const kafkaConfig = {
10
+ clientId: 'test-client',
11
+ brokers: process.env.KAFKA_BROKERS ? process.env.KAFKA_BROKERS.split(',') : ['localhost:9092'],
12
+ };
13
+
14
+ let messaging: KafkaMessaging;
15
+
16
+ beforeEach(() => {
17
+ messaging = new KafkaMessaging(kafkaConfig);
18
+ });
19
+
20
+ it('should create and track a producer', async () => {
21
+ const producer = await messaging.createProducer();
22
+ expect(producer).to.exist;
23
+ if (producer)
24
+ expect(messaging.activeProducers.has(producer)).to.be.true;
25
+ });
26
+
27
+ it('should create and track a consumer', async () => {
28
+ const consumer = await messaging.createConsumer('test-group');
29
+ expect(consumer).to.exist;
30
+ if (consumer)
31
+ expect(messaging.activeConsumers.has(consumer)).to.be.true;
32
+ });
33
+
34
+ it('should disconnect producer safely', async () => {
35
+ const producer = await messaging.createProducer();
36
+ expect(producer).to.exist;
37
+
38
+ if (producer) {
39
+ await messaging.safeDisconnect(producer);
40
+ expect(messaging.activeProducers.has(producer)).to.be.false;
41
+ }
42
+ });
43
+
44
+ it('should disconnect consumer safely', async () => {
45
+ const consumer = await messaging.createConsumer('test-group');
46
+ expect(consumer).to.exist;
47
+ if (consumer) {
48
+ await consumer.stop();
49
+ await messaging.safeDisconnect(consumer);
50
+ expect(messaging.activeConsumers.has(consumer)).to.be.false;
51
+ }
52
+ });
53
+
54
+ it('should shutdown all tracked clients', async () => {
55
+ await messaging.createProducer();
56
+ await messaging.createConsumer('test-group');
57
+ const result = await messaging.shutdown();
58
+ expect(result.successProducers).to.be.greaterThan(0);
59
+ expect(result.successConsumers).to.be.greaterThan(0);
60
+ expect(result.errorCount).to.equal(0);
61
+ });
62
+ });
63
+
64
+ describe('KafkaMessaging Integration', function () {
65
+ this.timeout(20000); // Increase timeout for Kafka operations
66
+
67
+ const kafkaConfig = {
68
+ clientId: 'integration-client',
69
+ brokers: process.env.KAFKA_BROKERS ? process.env.KAFKA_BROKERS.split(',') : ['localhost:9092'],
70
+ };
71
+
72
+ let messaging: KafkaMessaging;
73
+
74
+ beforeEach(() => {
75
+ messaging = new KafkaMessaging(kafkaConfig);
76
+ });
77
+
78
+ afterEach(async () => {
79
+ await messaging.shutdown();
80
+ });
81
+
82
+ it('should publish and consume a message', async () => {
83
+ const topic = 'test-topic-c';
84
+ await messaging.createTopic({
85
+ topic,
86
+ numPartitions: 1,
87
+ replicationFactor: 1
88
+ }, {
89
+ waitForLeaders: true
90
+ });
91
+ await messaging.waitForTopicReady(topic); // 👈 wait for metadata to settle
92
+
93
+ const message = { hello: 'world' };
94
+
95
+ let received: unknown = null;
96
+
97
+ await messaging.subscribe(topic, (msg) => {
98
+ received = msg;
99
+ }, { fromBeginning: true });
100
+
101
+ await messaging.publish(topic, message);
102
+
103
+ // Wait for message to be consumed
104
+ await new Promise(resolve => setTimeout(resolve, 1000));
105
+
106
+ expect(received).to.deep.equal(message);
107
+ });
108
+
109
+ it('should return correct shutdown summary', async () => {
110
+ const topic = 'shutdown-topic-c';
111
+ await messaging.createTopic({
112
+ topic,
113
+ numPartitions: 1,
114
+ replicationFactor: 1
115
+ }, {
116
+ waitForLeaders: true
117
+ });
118
+ await messaging.waitForTopicReady(topic); // 👈 wait for metadata to settle
119
+
120
+ await messaging.subscribe(topic, () => { }, { fromBeginning: true });
121
+ await messaging.publish(topic, { test: true });
122
+
123
+ const result = await messaging.shutdown();
124
+
125
+ expect(result.successProducers).to.be.greaterThan(0);
126
+ expect(result.successConsumers).to.be.greaterThan(0);
127
+ expect(result.errorCount).to.equal(0);
128
+ });
129
+ });