@woovi/kafka 0.1.6 → 0.1.7

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/dist/index.cjs CHANGED
@@ -109,13 +109,25 @@ function registerGracefulShutdown() {
109
109
  function onShutdown(callback) {
110
110
  shutdownCallbacks.push(callback);
111
111
  }
112
- let mockKafkaForTestMode = null;
112
+ const WOOVI_KAFKA_MOCK_KEY = '__woovi_kafka_mock__';
113
+ function getGlobalState() {
114
+ const g = globalThis;
115
+ if (!g[WOOVI_KAFKA_MOCK_KEY]) g[WOOVI_KAFKA_MOCK_KEY] = {
116
+ mock: null,
117
+ testMode: false
118
+ };
119
+ return g[WOOVI_KAFKA_MOCK_KEY];
120
+ }
113
121
  function setMockKafkaForTestMode(mock) {
114
- mockKafkaForTestMode = mock;
122
+ const state = getGlobalState();
123
+ state.mock = mock;
124
+ state.testMode = true;
115
125
  testMode = true;
116
126
  }
117
127
  function getKafka() {
118
- if (testMode && mockKafkaForTestMode) return mockKafkaForTestMode;
128
+ const state = getGlobalState();
129
+ if (state.testMode && state.mock) return state.mock;
130
+ if (testMode && kafkaInstance) return kafkaInstance;
119
131
  if (!kafkaInstance) throw new Error('Kafka not initialized. Call createKafka() first.');
120
132
  return kafkaInstance;
121
133
  }
@@ -0,0 +1,197 @@
1
+ import type { CompressionTypes } from 'kafkajs';
2
+ import type { Consumer } from 'kafkajs';
3
+ import type { ConsumerConfig } from 'kafkajs';
4
+ import type { ConsumerSubscribeTopics } from 'kafkajs';
5
+ import { Counter } from 'prom-client';
6
+ import type { EachBatchPayload } from 'kafkajs';
7
+ import type { EachMessagePayload } from 'kafkajs';
8
+ import { Gauge } from 'prom-client';
9
+ import { Histogram } from 'prom-client';
10
+ import { Kafka } from 'kafkajs';
11
+ import type { KafkaConfig as KafkaConfig_2 } from 'kafkajs';
12
+ import { logLevel } from 'kafkajs';
13
+ import type { Message } from 'kafkajs';
14
+ import type { Producer } from 'kafkajs';
15
+ import type { ProducerConfig } from 'kafkajs';
16
+ import type { RecordMetadata } from 'kafkajs';
17
+ import { Registry } from 'prom-client';
18
+
19
+ export declare interface BatchHandler {
20
+ (payload: EachBatchPayload): Promise<void>;
21
+ }
22
+
23
+ export declare const batchProcessingDuration: Histogram<"topic" | "group_id" | "partition">;
24
+
25
+ export declare const batchSize: Histogram<"topic" | "group_id" | "partition">;
26
+
27
+ export declare const consumerLag: Gauge<"topic" | "group_id" | "partition">;
28
+
29
+ export declare function createConsumer(config: WooviConsumerConfig): WooviConsumer;
30
+
31
+ export declare function createKafka(config: KafkaConfig): Kafka;
32
+
33
+ export declare function createKafkaFromEnv(clientId: string): Kafka;
34
+
35
+ export declare function createProducer(config?: WooviProducerConfig): WooviProducer;
36
+
37
+ /**
38
+ * Disable test mode and reset the Kafka instance.
39
+ */
40
+ export declare function disableTestMode(): void;
41
+
42
+ export { EachBatchPayload }
43
+
44
+ export { EachMessagePayload }
45
+
46
+ export declare function enableDefaultMetrics(): void;
47
+
48
+ /**
49
+ * Enable test mode with a mock Kafka instance.
50
+ * This allows tests to bypass the real Kafka connection.
51
+ */
52
+ export declare function enableTestMode(mockKafka?: Kafka): void;
53
+
54
+ export declare interface ErrorHandler {
55
+ (error: Error, payload: EachMessagePayload): Promise<void>;
56
+ }
57
+
58
+ export declare function getKafka(): Kafka;
59
+
60
+ export declare function getMessageHeaders(payload: EachMessagePayload): Record<string, string>;
61
+
62
+ export declare function getMetrics(): Promise<string>;
63
+
64
+ export declare function getMetricsContentType(): string;
65
+
66
+ export declare function healthCheck(): Promise<{
67
+ healthy: boolean;
68
+ error?: string;
69
+ }>;
70
+
71
+ /**
72
+ * Check if test mode is enabled.
73
+ */
74
+ export declare function isTestMode(): boolean;
75
+
76
+ export { Kafka }
77
+
78
+ export declare interface KafkaConfig {
79
+ brokers: string[];
80
+ clientId: string;
81
+ ssl?: KafkaConfig_2['ssl'];
82
+ sasl?: KafkaConfig_2['sasl'];
83
+ connectionTimeout?: number;
84
+ requestTimeout?: number;
85
+ retry?: KafkaConfig_2['retry'];
86
+ }
87
+
88
+ export declare const kafkaRegistry: Registry<"text/plain; version=0.0.4; charset=utf-8">;
89
+
90
+ export declare const lastMessageTimestamp: Gauge<"topic" | "group_id" | "partition">;
91
+
92
+ export { logLevel }
93
+
94
+ export { Message }
95
+
96
+ export declare interface MessageHandler {
97
+ (payload: EachMessagePayload): Promise<void>;
98
+ }
99
+
100
+ export declare const messageProcessingDuration: Histogram<"topic" | "group_id" | "partition">;
101
+
102
+ export declare const messagesFailedTotal: Counter<"topic" | "group_id" | "partition" | "error_type">;
103
+
104
+ export declare const messagesProcessedTotal: Counter<"topic" | "group_id" | "partition" | "status">;
105
+
106
+ export declare const messagesProducedTotal: Counter<"topic" | "status">;
107
+
108
+ export declare function onShutdown(callback: () => Promise<void>): void;
109
+
110
+ export declare function parseMessage<T>(payload: EachMessagePayload): T | null;
111
+
112
+ export declare const produceLatency: Histogram<"topic">;
113
+
114
+ export declare interface PublishArgs<T = unknown> {
115
+ data: T;
116
+ topic?: string;
117
+ key?: string;
118
+ partition?: number;
119
+ headers?: Record<string, string>;
120
+ timestamp?: string;
121
+ compression?: CompressionTypes;
122
+ }
123
+
124
+ export declare interface PublishBatchArgs<T = unknown> {
125
+ messages: Array<{
126
+ data: T;
127
+ key?: string;
128
+ partition?: number;
129
+ headers?: Record<string, string>;
130
+ timestamp?: string;
131
+ }>;
132
+ topic?: string;
133
+ compression?: CompressionTypes;
134
+ }
135
+
136
+ export declare interface PublishMultiTopicArgs<T = unknown> {
137
+ messages: Array<{
138
+ topic: string;
139
+ data: T;
140
+ key?: string;
141
+ partition?: number;
142
+ headers?: Record<string, string>;
143
+ timestamp?: string;
144
+ }>;
145
+ }
146
+
147
+ export { RecordMetadata }
148
+
149
+ export declare function resetMetrics(): void;
150
+
151
+ export declare function setMockKafkaForTestMode(mock: Kafka): void;
152
+
153
+ export declare class WooviConsumer {
154
+ private consumer;
155
+ private topics;
156
+ private fromBeginning;
157
+ private connected;
158
+ private subscribed;
159
+ private groupId;
160
+ private onError?;
161
+ constructor(config: WooviConsumerConfig);
162
+ connect(): Promise<void>;
163
+ subscribe(): Promise<void>;
164
+ disconnect(): Promise<void>;
165
+ isConnected(): boolean;
166
+ run(handler: MessageHandler): Promise<void>;
167
+ runBatch(handler: BatchHandler): Promise<void>;
168
+ pause(topics?: string[]): Promise<void>;
169
+ resume(topics?: string[]): Promise<void>;
170
+ getConsumer(): Consumer;
171
+ }
172
+
173
+ export declare interface WooviConsumerConfig extends ConsumerConfig {
174
+ topics: ConsumerSubscribeTopics['topics'];
175
+ fromBeginning?: boolean;
176
+ onError?: ErrorHandler;
177
+ }
178
+
179
+ export declare class WooviProducer {
180
+ private producer;
181
+ private defaultTopic?;
182
+ private connected;
183
+ constructor(config?: WooviProducerConfig);
184
+ connect(): Promise<void>;
185
+ disconnect(): Promise<void>;
186
+ isConnected(): boolean;
187
+ publish<T>(args: PublishArgs<T>): Promise<RecordMetadata[]>;
188
+ publishBatch<T>(args: PublishBatchArgs<T>): Promise<RecordMetadata[]>;
189
+ publishToMultipleTopics<T>(args: PublishMultiTopicArgs<T>): Promise<RecordMetadata[]>;
190
+ getProducer(): Producer;
191
+ }
192
+
193
+ export declare interface WooviProducerConfig extends ProducerConfig {
194
+ defaultTopic?: string;
195
+ }
196
+
197
+ export { }
package/dist/index.js CHANGED
@@ -52,13 +52,25 @@ function registerGracefulShutdown() {
52
52
  function onShutdown(callback) {
53
53
  shutdownCallbacks.push(callback);
54
54
  }
55
- let mockKafkaForTestMode = null;
55
+ const WOOVI_KAFKA_MOCK_KEY = '__woovi_kafka_mock__';
56
+ function getGlobalState() {
57
+ const g = globalThis;
58
+ if (!g[WOOVI_KAFKA_MOCK_KEY]) g[WOOVI_KAFKA_MOCK_KEY] = {
59
+ mock: null,
60
+ testMode: false
61
+ };
62
+ return g[WOOVI_KAFKA_MOCK_KEY];
63
+ }
56
64
  function setMockKafkaForTestMode(mock) {
57
- mockKafkaForTestMode = mock;
65
+ const state = getGlobalState();
66
+ state.mock = mock;
67
+ state.testMode = true;
58
68
  testMode = true;
59
69
  }
60
70
  function getKafka() {
61
- if (testMode && mockKafkaForTestMode) return mockKafkaForTestMode;
71
+ const state = getGlobalState();
72
+ if (state.testMode && state.mock) return state.mock;
73
+ if (testMode && kafkaInstance) return kafkaInstance;
62
74
  if (!kafkaInstance) throw new Error('Kafka not initialized. Call createKafka() first.');
63
75
  return kafkaInstance;
64
76
  }
@@ -37,6 +37,7 @@ __webpack_require__.d(__webpack_exports__, {
37
37
  mockProducerSend: ()=>mockProducerSend,
38
38
  mockTransaction: ()=>mockTransaction,
39
39
  mockTransactionSend: ()=>mockTransactionSend,
40
+ setupKafkaTest: ()=>setupKafkaTest,
40
41
  KafkaJSNonRetriableError: ()=>KafkaJSNonRetriableError,
41
42
  CompressionTypes: ()=>CompressionTypes,
42
43
  mockProducer: ()=>mockProducer
@@ -204,12 +205,20 @@ const kafkaAssertLength = (args)=>{
204
205
  }
205
206
  };
206
207
  function createMockKafka() {
207
- return Kafka({
208
- clientId: 'test',
209
- brokers: [
210
- 'localhost:9092'
211
- ]
212
- });
208
+ return Kafka();
209
+ }
210
+ const WOOVI_KAFKA_MOCK_KEY = '__woovi_kafka_mock__';
211
+ function setupKafkaTest() {
212
+ const mockKafkaInstance = {
213
+ producer: mockProducer,
214
+ consumer: mockConsumer,
215
+ admin: mockAdmin
216
+ };
217
+ const g = globalThis;
218
+ g[WOOVI_KAFKA_MOCK_KEY] = {
219
+ mock: mockKafkaInstance,
220
+ testMode: true
221
+ };
213
222
  }
214
223
  exports.CompressionTypes = __webpack_exports__.CompressionTypes;
215
224
  exports.Kafka = __webpack_exports__.Kafka;
@@ -227,6 +236,7 @@ exports.mockProducer = __webpack_exports__.mockProducer;
227
236
  exports.mockProducerSend = __webpack_exports__.mockProducerSend;
228
237
  exports.mockTransaction = __webpack_exports__.mockTransaction;
229
238
  exports.mockTransactionSend = __webpack_exports__.mockTransactionSend;
239
+ exports.setupKafkaTest = __webpack_exports__.setupKafkaTest;
230
240
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
231
241
  "CompressionTypes",
232
242
  "Kafka",
@@ -243,7 +253,8 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
243
253
  "mockProducer",
244
254
  "mockProducerSend",
245
255
  "mockTransaction",
246
- "mockTransactionSend"
256
+ "mockTransactionSend",
257
+ "setupKafkaTest"
247
258
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
248
259
  Object.defineProperty(exports, '__esModule', {
249
260
  value: true
@@ -0,0 +1,110 @@
1
+ export declare const clearAllMocks: () => void;
2
+
3
+ export declare const CompressionTypes: {
4
+ None: number;
5
+ GZIP: number;
6
+ Snappy: number;
7
+ LZ4: number;
8
+ ZSTD: number;
9
+ };
10
+
11
+ /**
12
+ * Create a mock Kafka instance for testing.
13
+ * Use this with setMockKafkaForTestMode from @woovi/kafka.
14
+ *
15
+ * @example
16
+ * import { setMockKafkaForTestMode } from '@woovi/kafka';
17
+ * import { createMockKafka } from '@woovi/kafka/test-utils';
18
+ *
19
+ * beforeAll(() => {
20
+ * setMockKafkaForTestMode(createMockKafka());
21
+ * });
22
+ */
23
+ export declare function createMockKafka(): any;
24
+
25
+ export declare const getKafkaMessages: () => KafkaMessage[];
26
+
27
+ export declare const Kafka: MockFn;
28
+
29
+ export declare const kafkaAssert: (args: KafkaAssertArgs) => void;
30
+
31
+ declare type KafkaAssertArgs = {
32
+ topic: string;
33
+ message: Record<string, unknown>;
34
+ };
35
+
36
+ export declare const kafkaAssertLength: (args: KafkaAssertLengthArgs) => void;
37
+
38
+ declare type KafkaAssertLengthArgs = {
39
+ topic: string;
40
+ length: number;
41
+ };
42
+
43
+ export declare class KafkaJSNonRetriableError extends Error {
44
+ constructor(message: string);
45
+ }
46
+
47
+ export declare class KafkaJSProtocolError extends Error {
48
+ type: string;
49
+ constructor(message: string, type: string);
50
+ }
51
+
52
+ export declare type KafkaMessage = {
53
+ topic: string;
54
+ messages: Array<{
55
+ key?: string;
56
+ value: string;
57
+ headers?: Record<string, string>;
58
+ }>;
59
+ };
60
+
61
+ export declare const logLevel: {
62
+ NOTHING: number;
63
+ ERROR: number;
64
+ WARN: number;
65
+ INFO: number;
66
+ DEBUG: number;
67
+ };
68
+
69
+ export declare const mockAdmin: MockFn;
70
+
71
+ export declare const mockConsumer: MockFn;
72
+
73
+ declare type MockFn = {
74
+ (): any;
75
+ mock: {
76
+ calls: any[][];
77
+ };
78
+ mockClear: () => void;
79
+ mockReset: () => void;
80
+ mockImplementation: (fn: (...args: any[]) => any) => MockFn;
81
+ mockReturnValue: (value: any) => MockFn;
82
+ mockResolvedValue: (value: any) => MockFn;
83
+ };
84
+
85
+ export declare const mockProducer: MockFn;
86
+
87
+ export declare const mockProducerSend: MockFn;
88
+
89
+ export declare const mockTransaction: MockFn;
90
+
91
+ export declare const mockTransactionSend: MockFn;
92
+
93
+ /**
94
+ * Set up Kafka for testing with a mock instance.
95
+ * This creates a mock Kafka that records messages for kafkaAssert.
96
+ *
97
+ * @example
98
+ * import { setupKafkaTest, clearAllMocks } from '@woovi/kafka/test-utils';
99
+ *
100
+ * beforeAll(() => {
101
+ * setupKafkaTest();
102
+ * });
103
+ *
104
+ * beforeEach(() => {
105
+ * clearAllMocks();
106
+ * });
107
+ */
108
+ export declare function setupKafkaTest(): void;
109
+
110
+ export { }
@@ -161,11 +161,19 @@ const kafkaAssertLength = (args)=>{
161
161
  }
162
162
  };
163
163
  function createMockKafka() {
164
- return Kafka({
165
- clientId: 'test',
166
- brokers: [
167
- 'localhost:9092'
168
- ]
169
- });
164
+ return Kafka();
170
165
  }
171
- export { CompressionTypes, Kafka, KafkaJSNonRetriableError, KafkaJSProtocolError, clearAllMocks, createMockKafka, getKafkaMessages, kafkaAssert, kafkaAssertLength, logLevel, mockAdmin, mockConsumer, mockProducer, mockProducerSend, mockTransaction, mockTransactionSend };
166
+ const WOOVI_KAFKA_MOCK_KEY = '__woovi_kafka_mock__';
167
+ function setupKafkaTest() {
168
+ const mockKafkaInstance = {
169
+ producer: mockProducer,
170
+ consumer: mockConsumer,
171
+ admin: mockAdmin
172
+ };
173
+ const g = globalThis;
174
+ g[WOOVI_KAFKA_MOCK_KEY] = {
175
+ mock: mockKafkaInstance,
176
+ testMode: true
177
+ };
178
+ }
179
+ export { CompressionTypes, Kafka, KafkaJSNonRetriableError, KafkaJSProtocolError, clearAllMocks, createMockKafka, getKafkaMessages, kafkaAssert, kafkaAssertLength, logLevel, mockAdmin, mockConsumer, mockProducer, mockProducerSend, mockTransaction, mockTransactionSend, setupKafkaTest };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@woovi/kafka",
3
3
  "description": "Kafka setup and utilities for Woovi microservices",
4
- "version": "0.1.6",
4
+ "version": "0.1.7",
5
5
  "author": "",
6
6
  "type": "module",
7
7
  "dependencies": {