kafka-crab-js 0.7.0 → 1.0.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/README.md CHANGED
@@ -1,75 +1,254 @@
1
- # Kafka Crab Js
1
+ <div align="center">
2
2
 
3
- 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.
3
+ # 🦀 Kafka Crab JS 🦀
4
4
 
5
- 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).
5
+ A lightweight and flexible Kafka client for JavaScript/TypeScript, built with Rust-inspired reliability.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/kafka-crab-js.svg)](https://www.npmjs.com/package/kafka-crab-js)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ </div>
10
+
11
+ ## Features
12
+
13
+ - 🦀 Simple and intuitive API
14
+ - 🚀 High-performance message processing
15
+ - 🔄 Automatic reconnection handling
16
+ - 🎯 Type-safe interfaces (TypeScript support)
17
+ - ⚡ Async/await support
18
+ - 🛠️ Configurable consumer and producer options
19
+ - 📊 Stream processing support
20
+ - 📦 Message batching capabilities
21
+ - 🔍 Comprehensive error handling
6
22
 
7
23
  ## Table of Contents
8
- 1. [Installation](#installation)
9
- 2. [Usage](#usage)
10
- - [Client](#client)
11
- - [Producer](#producer)
12
- - [Consumer](#consumer)
13
- 3. [Examples](#examples)
14
24
 
25
+ 1. [Installation](#installation)
26
+ 2. [Quick Start](#quick-start)
27
+ 3. [Consumer Examples](#consumer-examples)
28
+ 4. [Producer Examples](#producer-examples)
29
+ 5. [Stream Processing](#stream-processing)
30
+ 6. [Configuration](#configuration)
31
+ 7. [Best Practices](#best-practices)
32
+ 8. [Contributing](#contributing)
33
+ 9. [License](#license)
15
34
 
16
35
  ## Installation
17
- 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:
18
36
 
19
- ```shell
37
+ ```bash
20
38
  npm install kafka-crab-js
39
+ # or
40
+ yarn add kafka-crab-js
21
41
  ```
22
- ## Usage
23
- ### Client
24
- Creating a Client Instance
25
- Next, you can create a client instance by specifying the Kafka broker(s) and other optional configurations:
42
+
43
+ ## Quick Start
44
+
45
+ ### Basic Consumer Setup
26
46
 
27
47
  ```javascript
28
- import { KafkaClient }
48
+ import { KafkaClient } from 'kafka-crab-js';
49
+ async function run() {
50
+ const kafkaClient = new KafkaClient({
51
+ brokers: 'localhost:29092',
52
+ clientId: 'foo-client',
53
+ logLevel: 'debug',
54
+ brokerAddressFamily: 'v4',
55
+ });
56
+
57
+ // Create consumer
58
+ const consumer = kafkaClient.createConsumer({
59
+ groupId: 'foo-group',
60
+ });
61
+
62
+ await consumer.subscribe([{ topic: 'foo' }]);
63
+
64
+ const message = await consumer.recv();
65
+ const { payload, partition, offset } = message;
66
+ console.log({
67
+ partition,
68
+ offset,
69
+ value: payload.toString()
70
+ });
71
+
72
+ consumer.unsubscribe();
73
+
74
+ }
75
+
76
+ await run();
77
+ ```
78
+
79
+ ### Basic Producer Setup
80
+
81
+ ```javascript
82
+ import { KafkaClient } from 'kafka-crab-js';
29
83
 
30
84
  const kafkaClient = new KafkaClient({
31
85
  brokers: 'localhost:29092',
32
- clientId: 'my-id'});
33
- ```
34
- ### Producer
35
- The producer component allows you to send messages to Kafka topics.
86
+ clientId: 'my-client-id',
87
+ logLevel: 'info',
88
+ brokerAddressFamily: 'v4',
89
+ });
36
90
 
37
- ```javascript
38
- const producer = kafkaClient.createProducer({topic: 'my-topic'});
91
+ const producer = kafkaClient.createProducer({ configuration: { 'message.timeout.ms': '5000' } });
92
+
93
+ const message = {
94
+ id: 1,
95
+ name: "Sample Message",
96
+ timestamp: new Date().toISOString()
97
+ };
39
98
 
40
99
  const result = await producer.send({
41
- topic: 'my-js-topic',
42
- messages: [{value: Buffer.from(`{"name":"Elizeu Drummond","phone":"55219123456"}`)}],
100
+ topic: 'my-topic',
101
+ messages: [{
102
+ payload: Buffer.from(JSON.stringify(message))
103
+ }]
43
104
  });
44
- console.log('Message sent with offset:', result);
45
- ```
46
105
 
106
+ const errors = result.map(r => r.error).filter(Boolean);
107
+ if (errors.length > 0) {
108
+ console.error('Error sending message:', errors);
109
+ } else {
110
+ console.log('Message sent. Offset:', result);
111
+ }
47
112
 
48
- ### Consumer
113
+ ```
49
114
 
50
- **Creating a Consumer Instance**
115
+ ## Stream Processing
51
116
 
52
- Create a consumer instance by specifying the Kafka broker(s), group ID, and other optional configurations:
117
+ ### Stream Consumer Example
53
118
 
54
119
  ```javascript
55
- const consumer = kafkaClient.createConsumer({
56
- topic: 'my-topic',
57
- groupId: 'my-group',
58
- retryStrategy: {
59
- retries: 3,
60
- },
120
+ import { KafkaClient } from 'kafka-crab-js';
121
+
122
+ const kafkaClient = new KafkaClient({
123
+ brokers: 'localhost:29092',
124
+ clientId: 'my-client-id',
125
+ logLevel: 'info',
126
+ brokerAddressFamily: 'v4',
127
+ });
128
+
129
+ const kafkaStream = kafkaClient.createStreamConsumer({
130
+ groupId: `my-groud-id`,
131
+ enableAutoCommit: true,
61
132
  });
133
+
134
+ await kafkaStream.subscribe([{ topic: 'foo' }, { topic: 'bar' }])
135
+
136
+ kafkaStream.on('data', (message) => {
137
+ console.log('>>> Message received:', { payload: message.payload.toString(), offset: message.offset, partition: message.partition, topic: message.topic })
138
+ if (message.offset > 10) {
139
+ kafkaStream.destroy();
140
+ }
141
+ })
142
+
143
+ kafkaStream.on('close', () => {
144
+ kafkaStream.unsubscribe();
145
+ console.log('Stream ended')
146
+ })
62
147
  ```
63
148
 
64
- You can consume messages using the run startConsumer:
149
+ ## Producer Examples
65
150
 
66
- ```javascript
67
- consumer.startConsumer(async (error, {value, partition, offset}) => {
68
- const message = JSON.parse(value.toString());
69
- console.log('Message received! Partition:', partition, 'Offset:', offset, 'Message =>', message.toString());
151
+ ### Batch Message Production
70
152
 
71
- return ConsumerResult.Ok;
153
+ ```javascript
154
+ const kafkaClient = new KafkaClient({
155
+ brokers: 'localhost:29092',
156
+ clientId: 'my-client-id',
157
+ brokerAddressFamily: 'v4',
72
158
  });
159
+ const producer = kafkaClient.createProducer({});
160
+
161
+ const messages = Array.from({ length: 100 }, (_, i) => ({
162
+ payload: Buffer.from(JSON.stringify({
163
+ _id: i,
164
+ name: `Batch Message ${i}`,
165
+ timestamp: new Date().toISOString()
166
+ }))
167
+ }));
168
+
169
+ try {
170
+ const result = await producer.send({
171
+ topic: 'my-topic',
172
+ messages
173
+ });
174
+ console.log('Batch sent. Offset:', result);
175
+ console.assert(result.length === 100);
176
+ } catch (error) {
177
+ console.error('Batch error:', error);
178
+ }
73
179
  ```
74
- ## Examples
75
- You can find examples of using Kafka Crab JS in the [GitHub repository](https://github.com/inaiat/kafka-crab-js).
180
+
181
+ ### Producer with Keys and Headers
182
+
183
+ ```javascript
184
+ async function produceWithMetadata() {
185
+ const producer = await kafkaCrab.createProducer({ config });
186
+
187
+ try {
188
+ await producer.send({
189
+ topic,
190
+ messages: [{
191
+ key: 'user-123',
192
+ payload: Buffer.from(JSON.stringify({
193
+ userId: 123,
194
+ action: 'update'
195
+ })),
196
+ headers: {
197
+ 'correlation-id': 'txn-123',
198
+ 'source': 'user-service'
199
+ }
200
+ }]
201
+ });
202
+ } catch (error) {
203
+ console.error('Error:', error);
204
+ }
205
+ }
206
+ ```
207
+
208
+ ## Configuration
209
+
210
+ ### Configuration properties
211
+
212
+ You can see the available options here: [librdkafka](https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md).
213
+
214
+ ## Best Practices
215
+
216
+ ### Error Handling
217
+ - Always wrap async operations in try-catch blocks
218
+ - Implement proper error logging and monitoring
219
+ - Handle both operational and programming errors separately
220
+
221
+ ### Performance
222
+ - Use batch operations for high-throughput scenarios
223
+ - Configure appropriate batch sizes and compression
224
+ - Monitor and tune consumer group performance
225
+
226
+ ### Resource Management
227
+ - Implement proper shutdown procedures
228
+ - Clean up resources (disconnect producers/consumers)
229
+ - Handle process signals (SIGTERM, SIGINT)
230
+
231
+ ### Message Processing
232
+ - Validate message formats before processing
233
+ - Implement proper serialization/deserialization
234
+ - Handle message ordering when required
235
+
236
+ ## Contributing
237
+
238
+ 1. Fork the repository
239
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
240
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
241
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
242
+ 5. Open a Pull Request
243
+
244
+ ## License
245
+
246
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
247
+
248
+ ---
249
+
250
+ <div align="center">
251
+
252
+ [![Built with Rust](https://img.shields.io/badge/Built%20with-Rust-orange)](https://www.rust-lang.org/)
253
+
254
+ </div>
package/index.d.ts CHANGED
@@ -1,131 +1,68 @@
1
- /* tslint:disable */
2
- /* eslint-disable */
3
-
4
- /* auto-generated by NAPI-RS */
5
-
6
- export const enum ConsumerResult {
7
- Ok = 'Ok',
8
- Retry = 'Retry'
9
- }
10
- export interface KafkaConsumerConfiguration {
11
- topic: string
12
- groupId: string
13
- retryStrategy?: RetryStrategy
14
- offset?: OffsetModel
15
- createTopic?: boolean
16
- commitMode?: CommitMode
17
- enableAutoCommit?: boolean
18
- configuration?: Record<string, string>
19
- fecthMetadataTimeout?: number
20
- }
21
- export interface RetryStrategy {
22
- retries: number
23
- retryTopic?: string
24
- dqlTopic?: string
25
- pauseConsumerDuration?: number
26
- offset?: OffsetModel
27
- configuration?: Record<string, string>
28
- }
29
- export const enum CommitMode {
30
- Sync = 0,
31
- Async = 1
32
- }
33
- export interface ConsumerConfiguration {
34
- groupId: string
35
- createTopic?: boolean
36
- enableAutoCommit?: boolean
37
- configuration?: Record<string, string>
38
- fecthMetadataTimeout?: number
39
- }
40
- export const enum PartitionPosition {
41
- Beginning = 'Beginning',
42
- End = 'End',
43
- Stored = 'Stored'
44
- }
45
- export interface OffsetModel {
46
- offset?: number
47
- position?: PartitionPosition
48
- }
49
- export interface PartitionOffset {
50
- partition: number
51
- offset: OffsetModel
52
- }
53
- export interface TopicPartitionConfig {
54
- topic: string
55
- allOffsets?: OffsetModel
56
- partitionOffset?: Array<PartitionOffset>
57
- }
58
- export const enum SecurityProtocol {
59
- Plaintext = 'Plaintext',
60
- Ssl = 'Ssl',
61
- SaslPlaintext = 'SaslPlaintext',
62
- SaslSsl = 'SaslSsl'
63
- }
64
- export interface KafkaConfiguration {
65
- brokers: string
66
- clientId: string
67
- securityProtocol?: SecurityProtocol
68
- configuration?: Record<string, string>
69
- logLevel?: string
70
- brokerAddressFamily?: string
71
- }
72
- export interface ProducerConfiguration {
73
- queueTimeout?: number
74
- thrownOnError?: boolean
75
- configuration?: Record<string, string>
76
- }
77
- export interface Payload {
78
- value: Buffer
79
- key?: Buffer
80
- headers?: Record<string, Buffer>
81
- topic: string
82
- partition: number
83
- offset: number
84
- }
85
- export interface Message {
86
- payload: Buffer
87
- key?: Buffer
88
- headers?: Record<string, Buffer>
89
- topic: string
90
- partition: number
91
- offset: number
92
- }
93
- export interface RecordMetadata {
94
- topic: string
95
- partition: number
96
- offset: number
97
- error?: KafkaCrabError
98
- }
99
- export interface MessageProducer {
100
- payload: Buffer
101
- key?: Buffer
102
- headers?: Record<string, Buffer>
103
- }
104
- export interface ProducerRecord {
105
- topic: string
106
- messages: Array<MessageProducer>
107
- }
108
- export interface KafkaCrabError {
109
- code: number
110
- message: string
111
- }
112
- export class KafkaConsumer {
113
- startConsumer(callback: (error: Error | undefined, result: Payload) => Promise<ConsumerResult | undefined>): Promise<void>
114
- }
115
- export class KafkaStreamConsumer {
116
- subscribe(topicConfigs: string | Array<TopicPartitionConfig>): Promise<void>
117
- unsubscribe(): void
118
- seek(topic: string, partition: number, offsetModel: OffsetModel, timeout?: number | undefined | null): void
119
- recv(): Promise<Message>
120
- commit(topic: string, partition: number, offset: number, commit: CommitMode): void
121
- }
1
+ /**
2
+ * KafkaClient class
3
+ */
122
4
  export class KafkaClient {
123
- readonly kafkaConfiguration: KafkaConfiguration
124
- constructor(kafkaConfiguration: KafkaConfiguration)
125
- createProducer(producerConfiguration: ProducerConfiguration): KafkaProducer
126
- createConsumer(consumerConfiguration: KafkaConsumerConfiguration): KafkaConsumer
127
- createStreamConsumer(consumerConfiguration: ConsumerConfiguration): KafkaStreamConsumer
128
- }
129
- export class KafkaProducer {
130
- send(producerRecord: ProducerRecord): Promise<Array<RecordMetadata>>
131
- }
5
+ /**
6
+ * Creates a KafkaStreamReadable instance
7
+ * @param { KafkaConfiguration } config
8
+ */
9
+ constructor(config: KafkaConfiguration);
10
+ kafkaConfiguration: KafkaConfiguration;
11
+ kafkaClientConfig: KafkaClientConfig;
12
+ /**
13
+ * Creates a KafkaProducer instance
14
+ * @param { ProducerConfiguration | undefined } producerConfiguration
15
+ * @returns {KafkaProducer}
16
+ */
17
+ createProducer(producerConfiguration: ProducerConfiguration | undefined): KafkaProducer;
18
+ /**
19
+ * Creates a KafkaConsumer instance
20
+ * @param {ConsumerConfiguration } consumerConfiguration
21
+ * @returns {KafkaConsumer}
22
+ */
23
+ createConsumer(consumerConfiguration: ConsumerConfiguration): KafkaConsumer;
24
+ /**
25
+ * Creates a KafkaStreamReadable instance
26
+ * @param { ConsumerConfiguration } consumerConfiguration
27
+ * @returns {KafkaStreamReadable}
28
+ */
29
+ createStreamConsumer(consumerConfiguration: ConsumerConfiguration): KafkaStreamReadable;
30
+ }
31
+ /**
32
+ * KafkaStreamReadable class
33
+ * @extends Readable
34
+ */
35
+ export class KafkaStreamReadable extends Readable {
36
+ /**
37
+ * Creates a KafkaStreamReadable instance
38
+ * @param { KafkaConsumer } kafkaConsumer
39
+ */
40
+ constructor(kafkaConsumer: KafkaConsumer);
41
+ kafkaConsumer: KafkaConsumer;
42
+ /**
43
+ * Subscribes to topics
44
+ * @param {string | Array<TopicPartitionConfig>} topics
45
+ * @returns
46
+ */
47
+ subscribe(topics: string | Array<TopicPartitionConfig>): Promise<void>;
48
+ /**
49
+ * Unsubscribe from topics
50
+ */
51
+ unsubscribe(): void;
52
+ /**
53
+ * The internal method called by the Readable stream to fetch data
54
+ */
55
+ _read(): Promise<void>;
56
+ }
57
+ import { ProducerConfiguration } from "./js-binding";
58
+ import { ConsumerConfiguration } from "./js-binding";
59
+ import { KafkaConfiguration } from "./js-binding";
60
+ import { KafkaConsumer } from "./js-binding";
61
+ import { CommitMode } from "./js-binding";
62
+ import { PartitionPosition } from "./js-binding";
63
+ import { SecurityProtocol } from "./js-binding";
64
+ import { KafkaClientConfig } from "./js-binding";
65
+ import { TopicPartitionConfig } from "./js-binding";
66
+ import { KafkaProducer } from "./js-binding";
67
+ import { Readable } from "stream";
68
+ export { ProducerConfiguration, ConsumerConfiguration, KafkaConfiguration, KafkaConsumer, CommitMode, PartitionPosition, SecurityProtocol, KafkaClientConfig, TopicPartitionConfig, KafkaProducer };