kafka-crab-js 0.0.9 → 0.1.0

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/Cargo.toml CHANGED
@@ -8,15 +8,16 @@ crate-type = ["cdylib"]
8
8
 
9
9
  [dependencies]
10
10
  # Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
11
- napi = { version = "2.13", default-features = false, features = [
12
- "napi4",
11
+ napi = { version = "2", default-features = false, features = [
12
+ "napi8",
13
13
  "tokio_rt",
14
+ "serde-json",
14
15
  ] }
15
- napi-derive = "2.13"
16
+ napi-derive = "2"
16
17
 
17
18
  anyhow = { version = "1.0", features = ["backtrace"] }
18
19
 
19
- rdkafka = { version = "0.32", features = [
20
+ rdkafka = { version = "0.33", features = [
20
21
  "libz-static",
21
22
  "cmake-build",
22
23
  "tokio",
package/README.md CHANGED
@@ -1,16 +1,77 @@
1
- Kafka Crab Js
2
- -------------
1
+ # Kafka Crab Js
3
2
 
4
3
  **Blazingly Fast Kafka Client for NodeJs**
5
4
 
6
5
  Kafka-Crab-JS is a powerful Node.js library that allows developers to interact with Apache Kafka using Rust programming language, seamlessly integrated with Node.js applications. This documentation provides an overview of the Kafka-Crab-JS library, including installation instructions, usage guidelines, and examples.
7
6
 
7
+ The plugin can be found on [npm](https://www.npmjs.com/package/kafka-crab-js) and the source code is available on [GitHub](https://github.com/inaiat/kafka-crab-js).
8
8
 
9
- # Installation
9
+ ## Table of Contents
10
+ 1. [Installation](#installation)
11
+ 2. [Usage](#usage)
12
+ - [Client](#client)
13
+ - [Producer](#producer)
14
+ - [Consumer](#consumer)
15
+ 3. [Examples](#examples)
10
16
 
11
- To use Kafka-Crab-JS in your Node.js project, follow the steps below:
12
17
 
13
- todo
18
+ ## Installation
19
+ To use Kafka Crab JS, you need to have Node.js and npm (Node Package Manager) installed on your system. Once you have them set up, you can install the plugin by running the following command:
14
20
 
15
- # Examples
16
- todo
21
+ ```shell
22
+ npm install kafka-crab-js
23
+ ```
24
+ ## Usage
25
+ ### Client
26
+ Creating a Client Instance
27
+ Next, you can create a client instance by specifying the Kafka broker(s) and other optional configurations:
28
+
29
+ ```javascript
30
+ import { KafkaClient }
31
+
32
+ const kafkaClient = new KafkaClient({
33
+ brokers: 'localhost:29092',
34
+ clientId: 'my-id'});
35
+ ```
36
+ ### Producer
37
+ The producer component allows you to send messages to Kafka topics.
38
+
39
+ ```javascript
40
+ const result = await producer.send({
41
+ topic: 'my-js-topic',
42
+ key: Buffer.from('abc'),
43
+ value: Buffer.from(`{"name":"Elizeu Drummond","phone":"55219123456"}`),
44
+ headers: {key: Buffer.from('value1')},
45
+ });
46
+ console.log('Message sent with offset:', result);
47
+ ```
48
+
49
+
50
+ ### Consumer
51
+
52
+ **Creating a Consumer Instance**
53
+
54
+ Create a consumer instance by specifying the Kafka broker(s), group ID, and other optional configurations:
55
+
56
+ ```javascript
57
+ const consumer = kafkaClient.createConsumer({
58
+ topic: 'my-js-topic',
59
+ groupId: 'my-js-group',
60
+ retryStrategy: {
61
+ retries: 3,
62
+ },
63
+ });
64
+ ```
65
+
66
+ You can consume messages using the run startConsumer:
67
+
68
+ ```javascript
69
+ consumer.startConsumer(async (error, value) => {
70
+ const message = JSON.parse(value.toString());
71
+ const content = await process_my_message(message);
72
+ return ConsumerResult.Ok;
73
+ });
74
+ ```
75
+ ## Examples
76
+
77
+ You can find examples of using Kafka Crab JS in the [GitHub repository](https://github.com/inaiat/kafka-crab-js).
@@ -1,73 +1,67 @@
1
1
  /* eslint-disable no-await-in-loop */
2
+
2
3
  import timersPromises from 'node:timers/promises';
3
4
  import {Buffer} from 'node:buffer';
4
- import {ConsumerResult, KafkaClient, KafkaCommitMode, PartitionPosition} from '../index.js';
5
-
6
- const kafkaClient = new KafkaClient({
7
- brokers: 'localhost:29092',
8
- clientId: 'my-id',
9
- enableAnsiLogger: false});
10
- const topic = 'my-js-topic';
11
-
12
- let counter = 0;
5
+ import {nanoid} from 'nanoid';
6
+ import {KafkaClient, CommitMode, PartitionPosition, ConsumerResult} from '../index.js';
13
7
 
14
- async function process(message) {
15
- await timersPromises.setTimeout(1);
16
- return 'message received: ' + JSON.stringify(message);
17
- }
8
+ const kafkaClient = new KafkaClient({
9
+ brokers: 'localhost:29092',
10
+ clientId: 'my-ids',
11
+ groupId: 'my-js-group',
12
+ enableAnsiLogger: true});
13
+ const topic = `topic-${nanoid()}`;
18
14
 
19
15
  const consumer = kafkaClient.createConsumer({
20
16
  topic,
21
17
  groupId: 'my-js-group',
22
- commitMode: KafkaCommitMode.Sync,
18
+ CommitMode: CommitMode.AutoCommit,
23
19
  offset: {position: PartitionPosition.Stored},
20
+ configuration: {'auto.offset.reset': 'earliest'},
24
21
  retryStrategy: {
25
- retries: 3,
22
+ retries: 5,
23
+ pauseConsumerDuration: 5000,
26
24
  },
27
25
  });
26
+ const producer = kafkaClient.createProducer({topic, configuration: {'message.timeout.ms': '5000'}});
28
27
 
29
- console.time('consumer');
30
-
31
- consumer.startConsumer(async (error, value) => {
32
- if (error) {
33
- console.error('Js Consumer error', error);
34
- return;
35
- }
36
-
37
- const message = JSON.parse(value.toString());
38
- const content = await process(message);
39
- counter++;
40
- if (counter >= 0) {
41
- console.timeEnd('consumer');
42
- console.log('Js Counter:', counter, 'Content:', JSON.stringify(content));
43
- console.time('consumer');
28
+ async function produce() {
29
+ for (let i = 0; i < 10; i++) {
30
+ try {
31
+ const result = await producer.send(
32
+ {
33
+ topic,
34
+ messages: [{value: Buffer.from(`{"_id":"${i}","name":"Elizeu Drummond Sample js","phone":"555"}`)}],
35
+ },
36
+ );
37
+ console.log('Js message sent. Offset:', result);
38
+ } catch (error) {
39
+ console.error('Js Error on send', error);
40
+ }
44
41
  }
42
+ }
45
43
 
46
- if (message._id === '3') {
47
- console.error('Js Error on process message, let\'s retry', JSON.stringify(content));
48
- return ConsumerResult.Retry;
49
- }
44
+ async function startConsumer() {
45
+ consumer.startConsumer(async (error, {value, partition, offset}) => {
46
+ if (error) {
47
+ console.error('Js Consumer error', error);
48
+ return;
49
+ }
50
50
 
51
+ const message = JSON.parse(value.toString());
51
52
 
52
- return ConsumerResult.Ok;
53
- });
53
+ console.log('Message received! Partition:', partition, 'Offset:', offset, 'Message =>', message);
54
54
 
55
- const producer = kafkaClient.createProducer({topic, configuration: {'message.timeout.ms': '5000'}});
56
- console.log('Sending message');
55
+ if (message._id === '5') {
56
+ return ConsumerResult.Retry;
57
+ }
57
58
 
58
- for (let i = 0; i < 5; i++) {
59
- try {
60
- const result = await producer.send(
61
- {
62
- topic,
63
- key: Buffer.from('abc'),
64
- value: Buffer.from(`{"_id":"${i}","name":"Elizeu Drummond Sample js","phone":"555"}`),
65
- headers: {key: Buffer.from('value1')},
66
- },
67
- );
68
- console.log("Js message sent. Offset: ", result);
69
- await timersPromises.setTimeout(1200);
70
- } catch (error) {
71
- console.error('Js Error on send', error);
72
- }
59
+ return ConsumerResult.Ok;
60
+ });
73
61
  }
62
+
63
+ console.time('consumer');
64
+
65
+ await startConsumer();
66
+
67
+ await produce();
package/index.d.ts CHANGED
@@ -16,27 +16,37 @@ export interface KafkaConfiguration {
16
16
  configuration?: Record<string, string>
17
17
  enableAnsiLogger?: boolean
18
18
  }
19
+ export const enum CommitMode {
20
+ AutoCommit = 'AutoCommit',
21
+ Sync = 'Sync',
22
+ Async = 'Async'
23
+ }
24
+ export interface RetryStrategy {
25
+ retries: number
26
+ retryTopic?: string
27
+ dqlTopic?: string
28
+ pauseConsumerDuration?: number
29
+ }
30
+ export const enum ConsumerResult {
31
+ Ok = 'Ok',
32
+ Retry = 'Retry'
33
+ }
19
34
  export interface ConsumerConfiguration {
20
35
  topic: string
21
36
  groupId: string
22
37
  retryStrategy?: RetryStrategy
23
38
  offset?: OffsetModel
24
39
  createTopic?: boolean
25
- commitMode?: KafkaCommitMode
40
+ commitMode?: CommitMode
26
41
  enableAutoCommit?: boolean
27
42
  configuration?: Record<string, string>
28
43
  }
29
44
  export interface ProducerConfiguration {
30
45
  queueTimeout?: number
46
+ thrownOnError?: boolean
31
47
  configuration?: Record<string, string>
32
48
  }
33
- export interface MessageModel {
34
- topic: string
35
- key: Buffer
36
- value: Buffer
37
- headers?: Record<string, Buffer>
38
- }
39
- export interface ProduceRecord {
49
+ export interface ProducerRecord {
40
50
  topic: string
41
51
  messages: Array<MessageModel>
42
52
  }
@@ -49,12 +59,11 @@ export const enum AutoOffsetReset {
49
59
  End = 'End',
50
60
  Error = 'Error'
51
61
  }
52
- export const enum KafkaCommitMode {
53
- AutoCommit = 'AutoCommit',
54
- Sync = 'Sync',
55
- Async = 'Async'
56
- }
57
- export interface OwnedDelivery {
62
+ export interface Payload {
63
+ value: Buffer
64
+ key?: Buffer
65
+ headers?: Record<string, Buffer>
66
+ topic: string
58
67
  partition: number
59
68
  offset: number
60
69
  }
@@ -67,15 +76,20 @@ export interface OffsetModel {
67
76
  offset?: number
68
77
  position?: PartitionPosition
69
78
  }
70
- export interface RetryStrategy {
71
- retries: number
72
- retryTopic?: string
73
- dqlTopic?: string
74
- pauseConsumerDuration?: number
79
+ export interface KafkaCrabError {
80
+ code: number
81
+ message: string
75
82
  }
76
- export const enum ConsumerResult {
77
- Ok = 'Ok',
78
- Retry = 'Retry'
83
+ export interface RecordMetadata {
84
+ topic: string
85
+ partition: number
86
+ offset: number
87
+ error?: KafkaCrabError
88
+ }
89
+ export interface MessageModel {
90
+ value: Buffer
91
+ key?: Buffer
92
+ headers?: Record<string, Buffer>
79
93
  }
80
94
  export class KafkaClient {
81
95
  readonly kafkaConfiguration: KafkaConfiguration
@@ -83,9 +97,10 @@ export class KafkaClient {
83
97
  createProducer(producerConfiguration: ProducerConfiguration): KafkaProducer
84
98
  createConsumer(consumerConfiguration: ConsumerConfiguration): KafkaConsumer
85
99
  }
100
+ export class ProducerHelper { }
86
101
  export class KafkaConsumer {
87
- startConsumer(callback: (err: Error | null, result: Buffer) => Promise<ConsumerResult | undefined>): Promise<void>
102
+ startConsumer(callback: (err: Error | null, result: Payload) => Promise<ConsumerResult | undefined>): Promise<void>
88
103
  }
89
104
  export class KafkaProducer {
90
- send(message: MessageModel): Promise<OwnedDelivery>
105
+ send(producerRecord: ProducerRecord): Promise<Array<RecordMetadata>>
91
106
  }
package/index.js CHANGED
@@ -252,13 +252,14 @@ if (!nativeBinding) {
252
252
  throw new Error(`Failed to load native binding`)
253
253
  }
254
254
 
255
- const { SecurityProtocol, KafkaClient, KafkaConsumer, KafkaProducer, AutoOffsetReset, KafkaCommitMode, PartitionPosition, ConsumerResult } = nativeBinding
255
+ const { SecurityProtocol, KafkaClient, CommitMode, ConsumerResult, ProducerHelper, KafkaConsumer, KafkaProducer, AutoOffsetReset, PartitionPosition } = nativeBinding
256
256
 
257
257
  module.exports.SecurityProtocol = SecurityProtocol
258
258
  module.exports.KafkaClient = KafkaClient
259
+ module.exports.CommitMode = CommitMode
260
+ module.exports.ConsumerResult = ConsumerResult
261
+ module.exports.ProducerHelper = ProducerHelper
259
262
  module.exports.KafkaConsumer = KafkaConsumer
260
263
  module.exports.KafkaProducer = KafkaProducer
261
264
  module.exports.AutoOffsetReset = AutoOffsetReset
262
- module.exports.KafkaCommitMode = KafkaCommitMode
263
265
  module.exports.PartitionPosition = PartitionPosition
264
- module.exports.ConsumerResult = ConsumerResult
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kafka-crab-js",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "napi": {
@@ -27,6 +27,8 @@
27
27
  "devDependencies": {
28
28
  "@napi-rs/cli": "^2.16.1",
29
29
  "ava": "^5.3.1",
30
+ "benny": "^3.7.1",
31
+ "kafkajs": "^2.2.4",
30
32
  "nanoid": "^4.0.2",
31
33
  "xo": "^0.54.2"
32
34
  },
@@ -37,7 +39,10 @@
37
39
  "node": ">= 10"
38
40
  },
39
41
  "xo": {
40
- "space": true
42
+ "space": true,
43
+ "rules": {
44
+ "new-cap": "off"
45
+ }
41
46
  },
42
47
  "scripts": {
43
48
  "artifacts": "napi artifacts",
@@ -50,8 +55,8 @@
50
55
  },
51
56
  "packageManager": "yarn@3.6.0",
52
57
  "optionalDependencies": {
53
- "kafka-crab-js-darwin-arm64": "0.0.9",
54
- "kafka-crab-js-darwin-x64": "0.0.9",
55
- "kafka-crab-js-linux-x64-gnu": "0.0.9"
58
+ "kafka-crab-js-darwin-arm64": "0.1.0",
59
+ "kafka-crab-js-darwin-x64": "0.1.0",
60
+ "kafka-crab-js-linux-x64-gnu": "0.1.0"
56
61
  }
57
62
  }