kafka-crab-js 1.0.1 → 1.0.3
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 +113 -6
- package/index.d.ts +4 -45
- package/index.js +14 -78
- package/kafka-client.d.ts +34 -0
- package/kafka-client.js +48 -0
- package/kafka-stream-readable.d.ts +31 -0
- package/kafka-stream-readable.js +59 -65
- package/package.json +13 -7
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# 🦀 Kafka Crab JS 🦀
|
|
4
4
|
|
|
5
|
-
A lightweight and
|
|
5
|
+
A lightweight, flexible, and reliable Kafka client for JavaScript/TypeScript. It is built using Rust and librdkafka, providing a high-performance and feature-rich Kafka client.
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/kafka-crab-js)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -205,12 +205,124 @@ async function produceWithMetadata() {
|
|
|
205
205
|
}
|
|
206
206
|
```
|
|
207
207
|
|
|
208
|
+
### Reconnecting Kafka Consumer
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
import { KafkaClient } from 'kafka-crab-js'
|
|
212
|
+
|
|
213
|
+
const kafkaClient = new KafkaClient({
|
|
214
|
+
brokers: 'localhost:29092',
|
|
215
|
+
clientId: 'reconnect-test',
|
|
216
|
+
logLevel: 'debug',
|
|
217
|
+
brokerAddressFamily: 'v4',
|
|
218
|
+
configuration: {
|
|
219
|
+
'auto.offset.reset': 'earliest',
|
|
220
|
+
},
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Creates and configures a new Kafka stream consumer
|
|
225
|
+
*/
|
|
226
|
+
async function createConsumer() {
|
|
227
|
+
const kafkaStream = kafkaClient.createStreamConsumer({
|
|
228
|
+
groupId: 'reconnect-test',
|
|
229
|
+
enableAutoCommit: true,
|
|
230
|
+
})
|
|
231
|
+
await kafkaStream.subscribe([
|
|
232
|
+
{ topic: 'foo' },
|
|
233
|
+
{ topic: 'bar' },
|
|
234
|
+
])
|
|
235
|
+
return kafkaStream
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Starts a Kafka consumer with auto-restart capability
|
|
240
|
+
*/
|
|
241
|
+
async function startConsumer() {
|
|
242
|
+
let counter = 0
|
|
243
|
+
let retryCount = 0
|
|
244
|
+
const MAX_RETRIES = 5
|
|
245
|
+
const RETRY_DELAY = 5000 // 5 seconds
|
|
246
|
+
|
|
247
|
+
async function handleRetry() {
|
|
248
|
+
if (retryCount < MAX_RETRIES) {
|
|
249
|
+
retryCount++
|
|
250
|
+
console.log(
|
|
251
|
+
`Attempting to restart consumer (attempt ${retryCount}/${MAX_RETRIES}) in ${RETRY_DELAY / 1000} seconds...`,
|
|
252
|
+
)
|
|
253
|
+
setTimeout(setupConsumerWithRetry, RETRY_DELAY)
|
|
254
|
+
} else {
|
|
255
|
+
console.error(`Maximum retry attempts (${MAX_RETRIES}) reached. Stopping consumer.`)
|
|
256
|
+
process.exit(1)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function setupConsumerWithRetry() {
|
|
261
|
+
try {
|
|
262
|
+
const kafkaStream = await createConsumer()
|
|
263
|
+
retryCount = 0 // Reset retry count on successful connection
|
|
264
|
+
|
|
265
|
+
console.log('Starting consumer')
|
|
266
|
+
|
|
267
|
+
kafkaStream.on('data', (message) => {
|
|
268
|
+
counter++
|
|
269
|
+
console.log('>>> Message received:', {
|
|
270
|
+
counter,
|
|
271
|
+
payload: message.payload.toString(),
|
|
272
|
+
offset: message.offset,
|
|
273
|
+
partition: message.partition,
|
|
274
|
+
topic: message.topic,
|
|
275
|
+
})
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
kafkaStream.on('error', async (error) => {
|
|
279
|
+
console.error('Stream error:', error)
|
|
280
|
+
handleRetry()
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
kafkaStream.on('close', () => {
|
|
284
|
+
console.log('Stream ended')
|
|
285
|
+
try {
|
|
286
|
+
kafkaStream.unsubscribe()
|
|
287
|
+
} catch (unsubError) {
|
|
288
|
+
console.error('Error unsubscribing:', unsubError)
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
} catch (error) {
|
|
292
|
+
console.error('Error setting up consumer:', error)
|
|
293
|
+
handleRetry()
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
await setupConsumerWithRetry()
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
await startConsumer()
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Examples
|
|
304
|
+
|
|
305
|
+
You can find some examples on the [example](https://github.com/mthssdrbrg/kafka-crab-js/tree/main/example) folder of this project.
|
|
306
|
+
|
|
208
307
|
## Configuration
|
|
209
308
|
|
|
210
309
|
### Configuration properties
|
|
211
310
|
|
|
311
|
+
### KafkaConfiguration
|
|
312
|
+
|
|
313
|
+
| Property | Type | Default | Description |
|
|
314
|
+
| --- | --- | --- | --- |
|
|
315
|
+
| `brokers` | `string` || List of brokers to connect to |
|
|
316
|
+
| `clientId` | `string` || Client id to use for the connection |
|
|
317
|
+
| `securityProtocol` | `SecurityProtocol` || Security protocol to use (PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL) |
|
|
318
|
+
| `logLevel` | `string` | `info` | Client id to use for the connection |
|
|
319
|
+
| `brokerAddressFamily` | `string` | `"v4"` | Address family to use for the connection (v4, v6) |
|
|
320
|
+
| `configuration` | `Map<string, string>` | `{}` | Additional configuration options for the client. See [librdkafka](https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md) |
|
|
321
|
+
|
|
212
322
|
You can see the available options here: [librdkafka](https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md).
|
|
213
323
|
|
|
324
|
+
|
|
325
|
+
|
|
214
326
|
## Best Practices
|
|
215
327
|
|
|
216
328
|
### Error Handling
|
|
@@ -223,11 +335,6 @@ You can see the available options here: [librdkafka](https://github.com/edenhill
|
|
|
223
335
|
- Configure appropriate batch sizes and compression
|
|
224
336
|
- Monitor and tune consumer group performance
|
|
225
337
|
|
|
226
|
-
### Resource Management
|
|
227
|
-
- Implement proper shutdown procedures
|
|
228
|
-
- Clean up resources (disconnect producers/consumers)
|
|
229
|
-
- Handle process signals (SIGTERM, SIGINT)
|
|
230
|
-
|
|
231
338
|
### Message Processing
|
|
232
339
|
- Validate message formats before processing
|
|
233
340
|
- Implement proper serialization/deserialization
|
package/index.d.ts
CHANGED
|
@@ -1,45 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
/**
|
|
6
|
-
* Creates a KafkaClient instance
|
|
7
|
-
* @param {KafkaConfiguration} config - The Kafka configuration object
|
|
8
|
-
* @throws {Error} If the configuration is invalid
|
|
9
|
-
*/
|
|
10
|
-
constructor(config: KafkaConfiguration);
|
|
11
|
-
kafkaConfiguration: KafkaConfiguration;
|
|
12
|
-
kafkaClientConfig: KafkaClientConfig;
|
|
13
|
-
/**
|
|
14
|
-
* Creates a KafkaProducer instance
|
|
15
|
-
* @param {ProducerConfiguration} [producerConfiguration] - Optional producer configuration
|
|
16
|
-
* @returns {KafkaProducer} A KafkaProducer instance
|
|
17
|
-
*/
|
|
18
|
-
createProducer(producerConfiguration?: ProducerConfiguration | undefined): KafkaProducer;
|
|
19
|
-
/**
|
|
20
|
-
* Creates a KafkaConsumer instance
|
|
21
|
-
* @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration
|
|
22
|
-
* @returns {KafkaConsumer} A KafkaConsumer instance
|
|
23
|
-
* @throws {Error} If the configuration is invalid
|
|
24
|
-
*/
|
|
25
|
-
createConsumer(consumerConfiguration: ConsumerConfiguration): KafkaConsumer;
|
|
26
|
-
/**
|
|
27
|
-
* Creates a KafkaStreamReadable instance
|
|
28
|
-
* @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration
|
|
29
|
-
* @returns {KafkaStreamReadable} A KafkaStreamReadable instance
|
|
30
|
-
* @throws {Error} If the configuration is invalid
|
|
31
|
-
*/
|
|
32
|
-
createStreamConsumer(consumerConfiguration: ConsumerConfiguration): KafkaStreamReadable;
|
|
33
|
-
}
|
|
34
|
-
import { KafkaStreamReadable } from "./kafka-stream-readable";
|
|
35
|
-
import { ProducerConfiguration } from "./js-binding";
|
|
36
|
-
import { ConsumerConfiguration } from "./js-binding";
|
|
37
|
-
import { KafkaConfiguration } from "./js-binding";
|
|
38
|
-
import { KafkaConsumer } from "./js-binding";
|
|
39
|
-
import { CommitMode } from "./js-binding";
|
|
40
|
-
import { PartitionPosition } from "./js-binding";
|
|
41
|
-
import { SecurityProtocol } from "./js-binding";
|
|
42
|
-
import { KafkaClientConfig } from "./js-binding";
|
|
43
|
-
import { TopicPartitionConfig } from "./js-binding";
|
|
44
|
-
import { KafkaProducer } from "./js-binding";
|
|
45
|
-
export { KafkaStreamReadable, ProducerConfiguration, ConsumerConfiguration, KafkaConfiguration, KafkaConsumer, CommitMode, PartitionPosition, SecurityProtocol, KafkaClientConfig, TopicPartitionConfig, KafkaProducer };
|
|
1
|
+
export type { ConsumerConfiguration, KafkaConfiguration, KafkaCrabError, Message, MessageProducer, OffsetModel, PartitionOffset, ProducerConfiguration, ProducerRecord, RecordMetadata, RetryStrategy, TopicPartitionConfig, } from './js-binding';
|
|
2
|
+
export { CommitMode, KafkaClientConfig, KafkaConsumer, KafkaProducer, PartitionPosition, SecurityProtocol, } from './js-binding';
|
|
3
|
+
export { KafkaClient } from './kafka-client';
|
|
4
|
+
export { KafkaStreamReadable } from './kafka-stream-readable';
|
package/index.js
CHANGED
|
@@ -1,78 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const { KafkaStreamReadable } = require('./kafka-stream-readable')
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* KafkaClient class
|
|
20
|
-
*/
|
|
21
|
-
class KafkaClient {
|
|
22
|
-
/**
|
|
23
|
-
* Creates a KafkaClient instance
|
|
24
|
-
* @param {KafkaConfiguration} config - The Kafka configuration object
|
|
25
|
-
* @throws {Error} If the configuration is invalid
|
|
26
|
-
*/
|
|
27
|
-
constructor(config) {
|
|
28
|
-
this.kafkaConfiguration = config
|
|
29
|
-
this.kafkaClientConfig = new KafkaClientConfig(config)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Creates a KafkaProducer instance
|
|
34
|
-
* @param {ProducerConfiguration} [producerConfiguration] - Optional producer configuration
|
|
35
|
-
* @returns {KafkaProducer} A KafkaProducer instance
|
|
36
|
-
*/
|
|
37
|
-
createProducer(producerConfiguration) {
|
|
38
|
-
if (producerConfiguration) {
|
|
39
|
-
return this.kafkaClientConfig.createProducer(producerConfiguration)
|
|
40
|
-
}
|
|
41
|
-
return this.kafkaClientConfig.createProducer({})
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Creates a KafkaConsumer instance
|
|
46
|
-
* @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration
|
|
47
|
-
* @returns {KafkaConsumer} A KafkaConsumer instance
|
|
48
|
-
* @throws {Error} If the configuration is invalid
|
|
49
|
-
*/
|
|
50
|
-
createConsumer(consumerConfiguration) {
|
|
51
|
-
return this.kafkaClientConfig.createConsumer(consumerConfiguration)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Creates a KafkaStreamReadable instance
|
|
56
|
-
* @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration
|
|
57
|
-
* @returns {KafkaStreamReadable} A KafkaStreamReadable instance
|
|
58
|
-
* @throws {Error} If the configuration is invalid
|
|
59
|
-
*/
|
|
60
|
-
createStreamConsumer(consumerConfiguration) {
|
|
61
|
-
return new KafkaStreamReadable(this.kafkaClientConfig.createConsumer(consumerConfiguration))
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
module.exports = {
|
|
66
|
-
KafkaClient,
|
|
67
|
-
KafkaStreamReadable,
|
|
68
|
-
ProducerConfiguration,
|
|
69
|
-
ConsumerConfiguration,
|
|
70
|
-
KafkaConfiguration,
|
|
71
|
-
KafkaConsumer,
|
|
72
|
-
CommitMode,
|
|
73
|
-
PartitionPosition,
|
|
74
|
-
SecurityProtocol,
|
|
75
|
-
KafkaClientConfig,
|
|
76
|
-
TopicPartitionConfig,
|
|
77
|
-
KafkaProducer,
|
|
78
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KafkaStreamReadable = exports.KafkaClient = exports.SecurityProtocol = exports.PartitionPosition = exports.KafkaProducer = exports.KafkaConsumer = exports.KafkaClientConfig = exports.CommitMode = void 0;
|
|
4
|
+
var js_binding_1 = require("./js-binding");
|
|
5
|
+
Object.defineProperty(exports, "CommitMode", { enumerable: true, get: function () { return js_binding_1.CommitMode; } });
|
|
6
|
+
Object.defineProperty(exports, "KafkaClientConfig", { enumerable: true, get: function () { return js_binding_1.KafkaClientConfig; } });
|
|
7
|
+
Object.defineProperty(exports, "KafkaConsumer", { enumerable: true, get: function () { return js_binding_1.KafkaConsumer; } });
|
|
8
|
+
Object.defineProperty(exports, "KafkaProducer", { enumerable: true, get: function () { return js_binding_1.KafkaProducer; } });
|
|
9
|
+
Object.defineProperty(exports, "PartitionPosition", { enumerable: true, get: function () { return js_binding_1.PartitionPosition; } });
|
|
10
|
+
Object.defineProperty(exports, "SecurityProtocol", { enumerable: true, get: function () { return js_binding_1.SecurityProtocol; } });
|
|
11
|
+
var kafka_client_1 = require("./kafka-client");
|
|
12
|
+
Object.defineProperty(exports, "KafkaClient", { enumerable: true, get: function () { return kafka_client_1.KafkaClient; } });
|
|
13
|
+
var kafka_stream_readable_1 = require("./kafka-stream-readable");
|
|
14
|
+
Object.defineProperty(exports, "KafkaStreamReadable", { enumerable: true, get: function () { return kafka_stream_readable_1.KafkaStreamReadable; } });
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ConsumerConfiguration, KafkaConfiguration, ProducerConfiguration } from './js-binding.js';
|
|
2
|
+
import { KafkaStreamReadable } from './kafka-stream-readable';
|
|
3
|
+
/**
|
|
4
|
+
* KafkaClient class
|
|
5
|
+
*/
|
|
6
|
+
export declare class KafkaClient {
|
|
7
|
+
private readonly kafkaConfiguration;
|
|
8
|
+
private readonly kafkaClientConfig;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a KafkaClient instance
|
|
11
|
+
* @throws {Error} If the configuration is invalid
|
|
12
|
+
*/
|
|
13
|
+
constructor(kafkaConfiguration: KafkaConfiguration);
|
|
14
|
+
/**
|
|
15
|
+
* Creates a KafkaProducer instance
|
|
16
|
+
* @param {ProducerConfiguration} [producerConfiguration] - Optional producer configuration
|
|
17
|
+
* @returns {KafkaProducer} A KafkaProducer instance
|
|
18
|
+
*/
|
|
19
|
+
createProducer(producerConfiguration: ProducerConfiguration): import("./js-binding.js").KafkaProducer;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a KafkaConsumer instance
|
|
22
|
+
* @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration
|
|
23
|
+
* @returns {KafkaConsumer} A KafkaConsumer instance
|
|
24
|
+
* @throws {Error} If the configuration is invalid
|
|
25
|
+
*/
|
|
26
|
+
createConsumer(consumerConfiguration: ConsumerConfiguration): import("./js-binding.js").KafkaConsumer;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a KafkaStreamReadable instance
|
|
29
|
+
* @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration
|
|
30
|
+
* @returns {KafkaStreamReadable} A KafkaStreamReadable instance
|
|
31
|
+
* @throws {Error} If the configuration is invalid
|
|
32
|
+
*/
|
|
33
|
+
createStreamConsumer(consumerConfiguration: ConsumerConfiguration): KafkaStreamReadable;
|
|
34
|
+
}
|
package/kafka-client.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KafkaClient = void 0;
|
|
4
|
+
const js_binding_js_1 = require("./js-binding.js");
|
|
5
|
+
const kafka_stream_readable_1 = require("./kafka-stream-readable");
|
|
6
|
+
/**
|
|
7
|
+
* KafkaClient class
|
|
8
|
+
*/
|
|
9
|
+
class KafkaClient {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a KafkaClient instance
|
|
12
|
+
* @throws {Error} If the configuration is invalid
|
|
13
|
+
*/
|
|
14
|
+
constructor(kafkaConfiguration) {
|
|
15
|
+
this.kafkaConfiguration = kafkaConfiguration;
|
|
16
|
+
this.kafkaClientConfig = new js_binding_js_1.KafkaClientConfig(kafkaConfiguration);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates a KafkaProducer instance
|
|
20
|
+
* @param {ProducerConfiguration} [producerConfiguration] - Optional producer configuration
|
|
21
|
+
* @returns {KafkaProducer} A KafkaProducer instance
|
|
22
|
+
*/
|
|
23
|
+
createProducer(producerConfiguration) {
|
|
24
|
+
if (producerConfiguration) {
|
|
25
|
+
return this.kafkaClientConfig.createProducer(producerConfiguration);
|
|
26
|
+
}
|
|
27
|
+
return this.kafkaClientConfig.createProducer({});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates a KafkaConsumer instance
|
|
31
|
+
* @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration
|
|
32
|
+
* @returns {KafkaConsumer} A KafkaConsumer instance
|
|
33
|
+
* @throws {Error} If the configuration is invalid
|
|
34
|
+
*/
|
|
35
|
+
createConsumer(consumerConfiguration) {
|
|
36
|
+
return this.kafkaClientConfig.createConsumer(consumerConfiguration);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Creates a KafkaStreamReadable instance
|
|
40
|
+
* @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration
|
|
41
|
+
* @returns {KafkaStreamReadable} A KafkaStreamReadable instance
|
|
42
|
+
* @throws {Error} If the configuration is invalid
|
|
43
|
+
*/
|
|
44
|
+
createStreamConsumer(consumerConfiguration) {
|
|
45
|
+
return new kafka_stream_readable_1.KafkaStreamReadable(this.kafkaClientConfig.createConsumer(consumerConfiguration));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.KafkaClient = KafkaClient;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Readable } from 'stream';
|
|
2
|
+
import { KafkaConsumer, TopicPartitionConfig } from './js-binding';
|
|
3
|
+
/**
|
|
4
|
+
* KafkaStreamReadable class
|
|
5
|
+
* @extends Readable
|
|
6
|
+
*/
|
|
7
|
+
export declare class KafkaStreamReadable extends Readable {
|
|
8
|
+
private readonly kafkaConsumer;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a KafkaStreamReadable instance
|
|
11
|
+
*/
|
|
12
|
+
constructor(kafkaConsumer: KafkaConsumer);
|
|
13
|
+
/**
|
|
14
|
+
* Subscribes to topics
|
|
15
|
+
*/
|
|
16
|
+
subscribe(topics: string | Array<TopicPartitionConfig>): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Unsubscribe from topics
|
|
19
|
+
*/
|
|
20
|
+
unsubscribe(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the raw Kafka consumer
|
|
23
|
+
* @returns {KafkaConsumer} The Kafka consumer instance
|
|
24
|
+
*/
|
|
25
|
+
rawConsumer(): KafkaConsumer;
|
|
26
|
+
/**
|
|
27
|
+
* Internal method called by the Readable stream to fetch data
|
|
28
|
+
* @private
|
|
29
|
+
*/
|
|
30
|
+
_read(): Promise<void>;
|
|
31
|
+
}
|
package/kafka-stream-readable.js
CHANGED
|
@@ -1,73 +1,67 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
TopicPartitionConfig,
|
|
6
|
-
} = require('./js-binding')
|
|
7
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KafkaStreamReadable = void 0;
|
|
4
|
+
const stream_1 = require("stream");
|
|
8
5
|
/**
|
|
9
6
|
* KafkaStreamReadable class
|
|
10
7
|
* @extends Readable
|
|
11
8
|
*/
|
|
12
|
-
class KafkaStreamReadable extends Readable {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
class KafkaStreamReadable extends stream_1.Readable {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a KafkaStreamReadable instance
|
|
12
|
+
*/
|
|
13
|
+
constructor(kafkaConsumer) {
|
|
14
|
+
super({ objectMode: true });
|
|
15
|
+
this.kafkaConsumer = kafkaConsumer;
|
|
16
|
+
if (!kafkaConsumer) {
|
|
17
|
+
throw new Error('A valid KafkaConsumer instance is required.');
|
|
18
|
+
}
|
|
19
|
+
this.kafkaConsumer = kafkaConsumer;
|
|
21
20
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
async subscribe(topics) {
|
|
31
|
-
if (!topics || (Array.isArray(topics) && topics.length === 0)) {
|
|
32
|
-
throw new Error('Topics must be a non-empty string or array.')
|
|
21
|
+
/**
|
|
22
|
+
* Subscribes to topics
|
|
23
|
+
*/
|
|
24
|
+
async subscribe(topics) {
|
|
25
|
+
if (!topics || (Array.isArray(topics) && topics.length === 0)) {
|
|
26
|
+
throw new Error('Topics must be a non-empty string or array.');
|
|
27
|
+
}
|
|
28
|
+
await this.kafkaConsumer.subscribe(topics);
|
|
33
29
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Unsubscribe from topics
|
|
32
|
+
*/
|
|
33
|
+
unsubscribe() {
|
|
34
|
+
this.kafkaConsumer.unsubscribe();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the raw Kafka consumer
|
|
38
|
+
* @returns {KafkaConsumer} The Kafka consumer instance
|
|
39
|
+
*/
|
|
40
|
+
rawConsumer() {
|
|
41
|
+
return this.kafkaConsumer;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Internal method called by the Readable stream to fetch data
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
async _read() {
|
|
48
|
+
try {
|
|
49
|
+
const message = await this.kafkaConsumer.recv(); // Call the napi-rs method
|
|
50
|
+
if (message) {
|
|
51
|
+
this.push(message); // Push message into the stream
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.push(null); // No more data, end of stream
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
this.destroy(error);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.destroy();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
67
65
|
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
module.exports = {
|
|
72
|
-
KafkaStreamReadable,
|
|
73
66
|
}
|
|
67
|
+
exports.KafkaStreamReadable = KafkaStreamReadable;
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kafka-crab-js",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"module": "commonjs",
|
|
7
7
|
"files": [
|
|
8
8
|
"index.d.ts",
|
|
9
9
|
"index.js",
|
|
10
|
+
"kafka-client.js",
|
|
11
|
+
"kafka-client.d.ts",
|
|
10
12
|
"kafka-stream-readable.js",
|
|
13
|
+
"kafka-stream-readable.d.ts",
|
|
11
14
|
"js-binding.js",
|
|
12
15
|
"js-binding.d.ts"
|
|
13
16
|
],
|
|
@@ -43,15 +46,18 @@
|
|
|
43
46
|
"ava": "6.2.0",
|
|
44
47
|
"dprint": "^0.47.5",
|
|
45
48
|
"nanoid": "5.0.8",
|
|
46
|
-
"typescript": "5.6.3"
|
|
49
|
+
"typescript": "5.6.3",
|
|
50
|
+
"copyfiles": "^2.4.1",
|
|
51
|
+
"@types/copyfiles": "^2.4.4",
|
|
52
|
+
"rimraf": "^6.0.1"
|
|
47
53
|
},
|
|
48
54
|
"ava": {
|
|
49
55
|
"timeout": "3m"
|
|
50
56
|
},
|
|
51
57
|
"scripts": {
|
|
52
58
|
"artifacts": "napi artifacts",
|
|
53
|
-
"build": "napi build --js js-binding.js --dts js-binding.d.ts --no-const-enum --platform --release",
|
|
54
|
-
"postbuild": "tsc",
|
|
59
|
+
"build": "napi build --js js-src/js-binding.js --dts js-src/js-binding.d.ts --no-const-enum --platform --release",
|
|
60
|
+
"postbuild": "rimraf dist && tsc && copyfiles -f js-src/js-binding.d.ts js-src/js-binding.js ./dist/*.js ./dist/*.d.ts .",
|
|
55
61
|
"build:debug": "napi build --platform",
|
|
56
62
|
"prepublishOnly": "napi prepublish -t npm",
|
|
57
63
|
"test": "ava",
|
|
@@ -61,8 +67,8 @@
|
|
|
61
67
|
},
|
|
62
68
|
"packageManager": "pnpm@9.14.2",
|
|
63
69
|
"optionalDependencies": {
|
|
64
|
-
"kafka-crab-js-darwin-arm64": "1.0.
|
|
65
|
-
"kafka-crab-js-darwin-x64": "1.0.
|
|
66
|
-
"kafka-crab-js-linux-x64-gnu": "1.0.
|
|
70
|
+
"kafka-crab-js-darwin-arm64": "1.0.3",
|
|
71
|
+
"kafka-crab-js-darwin-x64": "1.0.3",
|
|
72
|
+
"kafka-crab-js-linux-x64-gnu": "1.0.3"
|
|
67
73
|
}
|
|
68
74
|
}
|