@drarzter/kafka-client 0.5.1 → 0.5.2
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 +40 -4
- package/dist/{chunk-P7GY4BLV.mjs → chunk-VGUALBZH.mjs} +59 -27
- package/dist/chunk-VGUALBZH.mjs.map +1 -0
- package/dist/core.d.mts +3 -2
- package/dist/core.d.ts +3 -2
- package/dist/core.js +58 -26
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +1 -1
- package/dist/{envelope-CPX1qudy.d.mts → envelope-C66_h8r_.d.mts} +25 -3
- package/dist/{envelope-CPX1qudy.d.ts → envelope-C66_h8r_.d.ts} +25 -3
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +58 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/otel.d.mts +1 -1
- package/dist/otel.d.ts +1 -1
- package/dist/otel.js +1 -1
- package/dist/otel.js.map +1 -1
- package/dist/otel.mjs +1 -1
- package/dist/otel.mjs.map +1 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-P7GY4BLV.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ An opinionated, type-safe abstraction over `@confluentinc/kafka-javascript` (lib
|
|
|
16
16
|
- **Topic descriptors** — `topic()` DX sugar lets you define topics as standalone typed objects instead of string keys
|
|
17
17
|
- **Framework-agnostic** — use standalone or with NestJS (`register()` / `registerAsync()`, DI, lifecycle hooks)
|
|
18
18
|
- **Idempotent producer** — `acks: -1`, `idempotent: true` by default
|
|
19
|
-
- **Retry + DLQ** —
|
|
19
|
+
- **Retry + DLQ** — exponential backoff with full jitter; dead letter queue with error metadata headers (original topic, error message, stack, attempt count)
|
|
20
20
|
- **Batch sending** — send multiple messages in a single request
|
|
21
21
|
- **Batch consuming** — `startBatchConsumer()` for high-throughput `eachBatch` processing
|
|
22
22
|
- **Partition key support** — route related messages to the same partition
|
|
@@ -663,8 +663,9 @@ Options for `sendMessage()` — the third argument:
|
|
|
663
663
|
| `fromBeginning` | `false` | Read from the beginning of the topic |
|
|
664
664
|
| `autoCommit` | `true` | Auto-commit offsets |
|
|
665
665
|
| `retry.maxRetries` | — | Number of retry attempts |
|
|
666
|
-
| `retry.backoffMs` | `1000` | Base delay
|
|
667
|
-
| `
|
|
666
|
+
| `retry.backoffMs` | `1000` | Base delay for exponential backoff in ms |
|
|
667
|
+
| `retry.maxBackoffMs` | `30000` | Maximum delay cap for exponential backoff in ms |
|
|
668
|
+
| `dlq` | `false` | Send to `{topic}.dlq` after all retries exhausted — message carries `x-dlq-*` metadata headers |
|
|
668
669
|
| `interceptors` | `[]` | Array of before/after/onError hooks |
|
|
669
670
|
| `batch` | `false` | (decorator only) Use `startBatchConsumer` instead of `startConsumer` |
|
|
670
671
|
| `subscribeRetry.retries` | `5` | Max attempts for `consumer.subscribe()` when topic doesn't exist yet |
|
|
@@ -685,6 +686,7 @@ Passed to `KafkaModule.register()` or returned from `registerAsync()` factory:
|
|
|
685
686
|
| `numPartitions` | `1` | Number of partitions for auto-created topics |
|
|
686
687
|
| `strictSchemas` | `true` | Validate string topic keys against schemas registered via TopicDescriptor |
|
|
687
688
|
| `instrumentation` | `[]` | Client-wide instrumentation hooks (e.g. OTel). Applied to both send and consume paths |
|
|
689
|
+
| `onMessageLost` | — | Called when a message is silently dropped without DLQ — use to alert, log to external systems, or trigger fallback logic |
|
|
688
690
|
|
|
689
691
|
**Module-scoped** (default) — import `KafkaModule` in each module that needs it:
|
|
690
692
|
|
|
@@ -772,6 +774,31 @@ const interceptor: ConsumerInterceptor<MyTopics> = {
|
|
|
772
774
|
};
|
|
773
775
|
```
|
|
774
776
|
|
|
777
|
+
## onMessageLost
|
|
778
|
+
|
|
779
|
+
By default, if a consumer handler throws and `dlq` is not enabled, the message is logged and dropped. Use `onMessageLost` to catch these silent losses:
|
|
780
|
+
|
|
781
|
+
```typescript
|
|
782
|
+
import { KafkaClient, MessageLostContext } from '@drarzter/kafka-client/core';
|
|
783
|
+
|
|
784
|
+
const kafka = new KafkaClient('my-app', 'my-group', ['localhost:9092'], {
|
|
785
|
+
onMessageLost: (ctx: MessageLostContext) => {
|
|
786
|
+
// ctx.topic — topic the message came from
|
|
787
|
+
// ctx.error — what caused the failure
|
|
788
|
+
// ctx.attempt — number of attempts (0 = schema validation failed before handler ran)
|
|
789
|
+
// ctx.headers — original message headers (correlationId, traceparent, ...)
|
|
790
|
+
myAlertSystem.send(`Message lost on ${ctx.topic}: ${ctx.error.message}`);
|
|
791
|
+
},
|
|
792
|
+
});
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
`onMessageLost` fires in two cases:
|
|
796
|
+
|
|
797
|
+
1. **Handler error** — handler threw after all retries and `dlq: false`
|
|
798
|
+
2. **Validation error** — schema rejected the message and `dlq: false` (attempt is `0`)
|
|
799
|
+
|
|
800
|
+
It does NOT fire when `dlq: true` — in that case the message is preserved in `{topic}.dlq`.
|
|
801
|
+
|
|
775
802
|
## Schema validation
|
|
776
803
|
|
|
777
804
|
Add runtime message validation using any library with a `.parse()` method — Zod, Valibot, ArkType, or a custom validator. No extra dependency required.
|
|
@@ -835,11 +862,12 @@ Disable with `strictSchemas: false` in `KafkaModule.register()` options if you w
|
|
|
835
862
|
|
|
836
863
|
### Bring your own validator
|
|
837
864
|
|
|
838
|
-
Any object with `parse(data: unknown): T
|
|
865
|
+
Any object with `parse(data: unknown): T | Promise<T>` works — sync and async validators are both supported:
|
|
839
866
|
|
|
840
867
|
```typescript
|
|
841
868
|
import { SchemaLike } from '@drarzter/kafka-client';
|
|
842
869
|
|
|
870
|
+
// Sync validator
|
|
843
871
|
const customValidator: SchemaLike<{ id: string }> = {
|
|
844
872
|
parse(data: unknown) {
|
|
845
873
|
const d = data as any;
|
|
@@ -848,6 +876,14 @@ const customValidator: SchemaLike<{ id: string }> = {
|
|
|
848
876
|
},
|
|
849
877
|
};
|
|
850
878
|
|
|
879
|
+
// Async validator — e.g. remote schema registry lookup
|
|
880
|
+
const asyncValidator: SchemaLike<{ id: string }> = {
|
|
881
|
+
async parse(data: unknown) {
|
|
882
|
+
const schema = await fetchSchemaFromRegistry('my.topic');
|
|
883
|
+
return schema.validate(data);
|
|
884
|
+
},
|
|
885
|
+
};
|
|
886
|
+
|
|
851
887
|
const MyTopic = topic('my.topic').schema(customValidator);
|
|
852
888
|
```
|
|
853
889
|
|
|
@@ -115,7 +115,7 @@ async function validateWithSchema(message, raw, topic2, schemaMap, interceptors,
|
|
|
115
115
|
const schema = schemaMap.get(topic2);
|
|
116
116
|
if (!schema) return message;
|
|
117
117
|
try {
|
|
118
|
-
return schema.parse(message);
|
|
118
|
+
return await schema.parse(message);
|
|
119
119
|
} catch (error) {
|
|
120
120
|
const err = toError(error);
|
|
121
121
|
const validationError = new KafkaValidationError(topic2, message, {
|
|
@@ -125,20 +125,36 @@ async function validateWithSchema(message, raw, topic2, schemaMap, interceptors,
|
|
|
125
125
|
`Schema validation failed for topic ${topic2}:`,
|
|
126
126
|
err.message
|
|
127
127
|
);
|
|
128
|
-
if (dlq)
|
|
129
|
-
|
|
128
|
+
if (dlq) {
|
|
129
|
+
await sendToDlq(topic2, raw, deps, {
|
|
130
|
+
error: validationError,
|
|
131
|
+
attempt: 0,
|
|
132
|
+
originalHeaders: deps.originalHeaders
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
await deps.onMessageLost?.({ topic: topic2, error: validationError, attempt: 0, headers: deps.originalHeaders ?? {} });
|
|
136
|
+
}
|
|
137
|
+
const errorEnvelope = extractEnvelope(message, deps.originalHeaders ?? {}, topic2, -1, "");
|
|
130
138
|
for (const interceptor of interceptors) {
|
|
131
139
|
await interceptor.onError?.(errorEnvelope, validationError);
|
|
132
140
|
}
|
|
133
141
|
return null;
|
|
134
142
|
}
|
|
135
143
|
}
|
|
136
|
-
async function sendToDlq(topic2, rawMessage, deps) {
|
|
144
|
+
async function sendToDlq(topic2, rawMessage, deps, meta) {
|
|
137
145
|
const dlqTopic = `${topic2}.dlq`;
|
|
146
|
+
const headers = {
|
|
147
|
+
...meta?.originalHeaders ?? {},
|
|
148
|
+
"x-dlq-original-topic": topic2,
|
|
149
|
+
"x-dlq-failed-at": (/* @__PURE__ */ new Date()).toISOString(),
|
|
150
|
+
"x-dlq-error-message": meta?.error.message ?? "unknown",
|
|
151
|
+
"x-dlq-error-stack": meta?.error.stack?.slice(0, 2e3) ?? "",
|
|
152
|
+
"x-dlq-attempt-count": String(meta?.attempt ?? 0)
|
|
153
|
+
};
|
|
138
154
|
try {
|
|
139
155
|
await deps.producer.send({
|
|
140
156
|
topic: dlqTopic,
|
|
141
|
-
messages: [{ value: rawMessage }]
|
|
157
|
+
messages: [{ value: rawMessage, headers }]
|
|
142
158
|
});
|
|
143
159
|
deps.logger.warn(`Message sent to DLQ: ${dlqTopic}`);
|
|
144
160
|
} catch (error) {
|
|
@@ -152,6 +168,7 @@ async function executeWithRetry(fn, ctx, deps) {
|
|
|
152
168
|
const { envelope, rawMessages, interceptors, dlq, retry, isBatch } = ctx;
|
|
153
169
|
const maxAttempts = retry ? retry.maxRetries + 1 : 1;
|
|
154
170
|
const backoffMs = retry?.backoffMs ?? 1e3;
|
|
171
|
+
const maxBackoffMs = retry?.maxBackoffMs ?? 3e4;
|
|
155
172
|
const envelopes = Array.isArray(envelope) ? envelope : [envelope];
|
|
156
173
|
const topic2 = envelopes[0]?.topic ?? "unknown";
|
|
157
174
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
@@ -210,12 +227,25 @@ async function executeWithRetry(fn, ctx, deps) {
|
|
|
210
227
|
);
|
|
211
228
|
if (isLastAttempt) {
|
|
212
229
|
if (dlq) {
|
|
230
|
+
const dlqMeta = {
|
|
231
|
+
error: err,
|
|
232
|
+
attempt,
|
|
233
|
+
originalHeaders: envelopes[0]?.headers
|
|
234
|
+
};
|
|
213
235
|
for (const raw of rawMessages) {
|
|
214
|
-
await sendToDlq(topic2, raw, deps);
|
|
236
|
+
await sendToDlq(topic2, raw, deps, dlqMeta);
|
|
215
237
|
}
|
|
238
|
+
} else {
|
|
239
|
+
await deps.onMessageLost?.({
|
|
240
|
+
topic: topic2,
|
|
241
|
+
error: err,
|
|
242
|
+
attempt,
|
|
243
|
+
headers: envelopes[0]?.headers ?? {}
|
|
244
|
+
});
|
|
216
245
|
}
|
|
217
246
|
} else {
|
|
218
|
-
|
|
247
|
+
const cap = Math.min(backoffMs * 2 ** (attempt - 1), maxBackoffMs);
|
|
248
|
+
await sleep(Math.random() * cap);
|
|
219
249
|
}
|
|
220
250
|
}
|
|
221
251
|
}
|
|
@@ -257,6 +287,7 @@ var KafkaClient = class {
|
|
|
257
287
|
schemaRegistry = /* @__PURE__ */ new Map();
|
|
258
288
|
runningConsumers = /* @__PURE__ */ new Map();
|
|
259
289
|
instrumentation;
|
|
290
|
+
onMessageLost;
|
|
260
291
|
isAdminConnected = false;
|
|
261
292
|
clientId;
|
|
262
293
|
constructor(clientId, groupId, brokers, options) {
|
|
@@ -271,6 +302,7 @@ var KafkaClient = class {
|
|
|
271
302
|
this.strictSchemasEnabled = options?.strictSchemas ?? true;
|
|
272
303
|
this.numPartitions = options?.numPartitions ?? 1;
|
|
273
304
|
this.instrumentation = options?.instrumentation ?? [];
|
|
305
|
+
this.onMessageLost = options?.onMessageLost;
|
|
274
306
|
this.kafka = new KafkaClass({
|
|
275
307
|
kafkaJS: {
|
|
276
308
|
clientId: this.clientId,
|
|
@@ -286,7 +318,7 @@ var KafkaClient = class {
|
|
|
286
318
|
this.admin = this.kafka.admin();
|
|
287
319
|
}
|
|
288
320
|
async sendMessage(topicOrDesc, message, options = {}) {
|
|
289
|
-
const payload = this.buildSendPayload(topicOrDesc, [
|
|
321
|
+
const payload = await this.buildSendPayload(topicOrDesc, [
|
|
290
322
|
{
|
|
291
323
|
value: message,
|
|
292
324
|
key: options.key,
|
|
@@ -303,7 +335,7 @@ var KafkaClient = class {
|
|
|
303
335
|
}
|
|
304
336
|
}
|
|
305
337
|
async sendBatch(topicOrDesc, messages) {
|
|
306
|
-
const payload = this.buildSendPayload(topicOrDesc, messages);
|
|
338
|
+
const payload = await this.buildSendPayload(topicOrDesc, messages);
|
|
307
339
|
await this.ensureTopic(payload.topic);
|
|
308
340
|
await this.producer.send(payload);
|
|
309
341
|
for (const inst of this.instrumentation) {
|
|
@@ -327,7 +359,7 @@ var KafkaClient = class {
|
|
|
327
359
|
try {
|
|
328
360
|
const ctx = {
|
|
329
361
|
send: async (topicOrDesc, message, options = {}) => {
|
|
330
|
-
const payload = this.buildSendPayload(topicOrDesc, [
|
|
362
|
+
const payload = await this.buildSendPayload(topicOrDesc, [
|
|
331
363
|
{
|
|
332
364
|
value: message,
|
|
333
365
|
key: options.key,
|
|
@@ -341,7 +373,7 @@ var KafkaClient = class {
|
|
|
341
373
|
await tx.send(payload);
|
|
342
374
|
},
|
|
343
375
|
sendBatch: async (topicOrDesc, messages) => {
|
|
344
|
-
const payload = this.buildSendPayload(topicOrDesc, messages);
|
|
376
|
+
const payload = await this.buildSendPayload(topicOrDesc, messages);
|
|
345
377
|
await this.ensureTopic(payload.topic);
|
|
346
378
|
await tx.send(payload);
|
|
347
379
|
}
|
|
@@ -372,7 +404,7 @@ var KafkaClient = class {
|
|
|
372
404
|
}
|
|
373
405
|
async startConsumer(topics, handleMessage, options = {}) {
|
|
374
406
|
const { consumer, schemaMap, gid, dlq, interceptors, retry } = await this.setupConsumer(topics, "eachMessage", options);
|
|
375
|
-
const deps = { logger: this.logger, producer: this.producer, instrumentation: this.instrumentation };
|
|
407
|
+
const deps = { logger: this.logger, producer: this.producer, instrumentation: this.instrumentation, onMessageLost: this.onMessageLost };
|
|
376
408
|
await consumer.run({
|
|
377
409
|
eachMessage: async ({ topic: topic2, partition, message }) => {
|
|
378
410
|
if (!message.value) {
|
|
@@ -382,6 +414,7 @@ var KafkaClient = class {
|
|
|
382
414
|
const raw = message.value.toString();
|
|
383
415
|
const parsed = parseJsonMessage(raw, topic2, this.logger);
|
|
384
416
|
if (parsed === null) return;
|
|
417
|
+
const headers = decodeHeaders(message.headers);
|
|
385
418
|
const validated = await validateWithSchema(
|
|
386
419
|
parsed,
|
|
387
420
|
raw,
|
|
@@ -389,10 +422,9 @@ var KafkaClient = class {
|
|
|
389
422
|
schemaMap,
|
|
390
423
|
interceptors,
|
|
391
424
|
dlq,
|
|
392
|
-
deps
|
|
425
|
+
{ ...deps, originalHeaders: headers }
|
|
393
426
|
);
|
|
394
427
|
if (validated === null) return;
|
|
395
|
-
const headers = decodeHeaders(message.headers);
|
|
396
428
|
const envelope = extractEnvelope(
|
|
397
429
|
validated,
|
|
398
430
|
headers,
|
|
@@ -414,7 +446,7 @@ var KafkaClient = class {
|
|
|
414
446
|
}
|
|
415
447
|
async startBatchConsumer(topics, handleBatch, options = {}) {
|
|
416
448
|
const { consumer, schemaMap, gid, dlq, interceptors, retry } = await this.setupConsumer(topics, "eachBatch", options);
|
|
417
|
-
const deps = { logger: this.logger, producer: this.producer, instrumentation: this.instrumentation };
|
|
449
|
+
const deps = { logger: this.logger, producer: this.producer, instrumentation: this.instrumentation, onMessageLost: this.onMessageLost };
|
|
418
450
|
await consumer.run({
|
|
419
451
|
eachBatch: async ({
|
|
420
452
|
batch,
|
|
@@ -434,6 +466,7 @@ var KafkaClient = class {
|
|
|
434
466
|
const raw = message.value.toString();
|
|
435
467
|
const parsed = parseJsonMessage(raw, batch.topic, this.logger);
|
|
436
468
|
if (parsed === null) continue;
|
|
469
|
+
const headers = decodeHeaders(message.headers);
|
|
437
470
|
const validated = await validateWithSchema(
|
|
438
471
|
parsed,
|
|
439
472
|
raw,
|
|
@@ -441,10 +474,9 @@ var KafkaClient = class {
|
|
|
441
474
|
schemaMap,
|
|
442
475
|
interceptors,
|
|
443
476
|
dlq,
|
|
444
|
-
deps
|
|
477
|
+
{ ...deps, originalHeaders: headers }
|
|
445
478
|
);
|
|
446
479
|
if (validated === null) continue;
|
|
447
|
-
const headers = decodeHeaders(message.headers);
|
|
448
480
|
envelopes.push(
|
|
449
481
|
extractEnvelope(validated, headers, batch.topic, batch.partition, message.offset)
|
|
450
482
|
);
|
|
@@ -554,13 +586,13 @@ var KafkaClient = class {
|
|
|
554
586
|
}
|
|
555
587
|
}
|
|
556
588
|
/** Validate message against schema. Pure — no side-effects on registry. */
|
|
557
|
-
validateMessage(topicOrDesc, message) {
|
|
589
|
+
async validateMessage(topicOrDesc, message) {
|
|
558
590
|
if (topicOrDesc?.__schema) {
|
|
559
|
-
return topicOrDesc.__schema.parse(message);
|
|
591
|
+
return await topicOrDesc.__schema.parse(message);
|
|
560
592
|
}
|
|
561
593
|
if (this.strictSchemasEnabled && typeof topicOrDesc === "string") {
|
|
562
594
|
const schema = this.schemaRegistry.get(topicOrDesc);
|
|
563
|
-
if (schema) return schema.parse(message);
|
|
595
|
+
if (schema) return await schema.parse(message);
|
|
564
596
|
}
|
|
565
597
|
return message;
|
|
566
598
|
}
|
|
@@ -569,12 +601,11 @@ var KafkaClient = class {
|
|
|
569
601
|
* Handles: topic resolution, schema registration, validation, JSON serialization,
|
|
570
602
|
* envelope header generation, and instrumentation hooks.
|
|
571
603
|
*/
|
|
572
|
-
buildSendPayload(topicOrDesc, messages) {
|
|
604
|
+
async buildSendPayload(topicOrDesc, messages) {
|
|
573
605
|
this.registerSchema(topicOrDesc);
|
|
574
606
|
const topic2 = this.resolveTopicName(topicOrDesc);
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
messages: messages.map((m) => {
|
|
607
|
+
const builtMessages = await Promise.all(
|
|
608
|
+
messages.map(async (m) => {
|
|
578
609
|
const envelopeHeaders = buildEnvelopeHeaders({
|
|
579
610
|
correlationId: m.correlationId,
|
|
580
611
|
schemaVersion: m.schemaVersion,
|
|
@@ -585,12 +616,13 @@ var KafkaClient = class {
|
|
|
585
616
|
inst.beforeSend?.(topic2, envelopeHeaders);
|
|
586
617
|
}
|
|
587
618
|
return {
|
|
588
|
-
value: JSON.stringify(this.validateMessage(topicOrDesc, m.value)),
|
|
619
|
+
value: JSON.stringify(await this.validateMessage(topicOrDesc, m.value)),
|
|
589
620
|
key: m.key ?? null,
|
|
590
621
|
headers: envelopeHeaders
|
|
591
622
|
};
|
|
592
623
|
})
|
|
593
|
-
|
|
624
|
+
);
|
|
625
|
+
return { topic: topic2, messages: builtMessages };
|
|
594
626
|
}
|
|
595
627
|
/** Shared consumer setup: groupId check, schema map, connect, subscribe. */
|
|
596
628
|
async setupConsumer(topics, mode, options) {
|
|
@@ -680,4 +712,4 @@ export {
|
|
|
680
712
|
KafkaClient,
|
|
681
713
|
topic
|
|
682
714
|
};
|
|
683
|
-
//# sourceMappingURL=chunk-
|
|
715
|
+
//# sourceMappingURL=chunk-VGUALBZH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/kafka.client.ts","../src/client/envelope.ts","../src/client/errors.ts","../src/client/consumer-pipeline.ts","../src/client/subscribe-retry.ts","../src/client/topic.ts"],"sourcesContent":["import { KafkaJS } from \"@confluentinc/kafka-javascript\";\ntype Kafka = KafkaJS.Kafka;\ntype Producer = KafkaJS.Producer;\ntype Consumer = KafkaJS.Consumer;\ntype Admin = KafkaJS.Admin;\nconst { Kafka: KafkaClass, logLevel: KafkaLogLevel } = KafkaJS;\nimport { TopicDescriptor, SchemaLike } from \"./topic\";\nimport {\n buildEnvelopeHeaders,\n decodeHeaders,\n extractEnvelope,\n runWithEnvelopeContext,\n} from \"./envelope\";\nimport type { EventEnvelope } from \"./envelope\";\nimport {\n toError,\n parseJsonMessage,\n validateWithSchema,\n executeWithRetry,\n} from \"./consumer-pipeline\";\nimport { subscribeWithRetry } from \"./subscribe-retry\";\nimport type {\n ClientId,\n GroupId,\n SendOptions,\n MessageHeaders,\n BatchMessageItem,\n ConsumerOptions,\n TransactionContext,\n TopicMapConstraint,\n IKafkaClient,\n KafkaClientOptions,\n KafkaInstrumentation,\n KafkaLogger,\n BatchMeta,\n} from \"./types\";\n\n// Re-export all types so existing `import { ... } from './kafka.client'` keeps working\nexport * from \"./types\";\n\n/**\n * Type-safe Kafka client.\n * Wraps @confluentinc/kafka-javascript (librdkafka) with JSON serialization,\n * retries, DLQ, transactions, and interceptors.\n *\n * @typeParam T - Topic-to-message type mapping for compile-time safety.\n */\nexport class KafkaClient<\n T extends TopicMapConstraint<T>,\n> implements IKafkaClient<T> {\n private readonly kafka: Kafka;\n private readonly producer: Producer;\n private txProducer: Producer | undefined;\n private readonly consumers = new Map<string, Consumer>();\n private readonly admin: Admin;\n private readonly logger: KafkaLogger;\n private readonly autoCreateTopicsEnabled: boolean;\n private readonly strictSchemasEnabled: boolean;\n private readonly numPartitions: number;\n private readonly ensuredTopics = new Set<string>();\n private readonly defaultGroupId: string;\n private readonly schemaRegistry = new Map<string, SchemaLike>();\n private readonly runningConsumers = new Map<string, \"eachMessage\" | \"eachBatch\">();\n private readonly instrumentation: KafkaInstrumentation[];\n private readonly onMessageLost: KafkaClientOptions['onMessageLost'];\n\n private isAdminConnected = false;\n public readonly clientId: ClientId;\n\n constructor(\n clientId: ClientId,\n groupId: GroupId,\n brokers: string[],\n options?: KafkaClientOptions,\n ) {\n this.clientId = clientId;\n this.defaultGroupId = groupId;\n this.logger = options?.logger ?? {\n log: (msg) => console.log(`[KafkaClient:${clientId}] ${msg}`),\n warn: (msg, ...args) => console.warn(`[KafkaClient:${clientId}] ${msg}`, ...args),\n error: (msg, ...args) => console.error(`[KafkaClient:${clientId}] ${msg}`, ...args),\n };\n this.autoCreateTopicsEnabled = options?.autoCreateTopics ?? false;\n this.strictSchemasEnabled = options?.strictSchemas ?? true;\n this.numPartitions = options?.numPartitions ?? 1;\n this.instrumentation = options?.instrumentation ?? [];\n this.onMessageLost = options?.onMessageLost;\n\n this.kafka = new KafkaClass({\n kafkaJS: {\n clientId: this.clientId,\n brokers,\n logLevel: KafkaLogLevel.ERROR,\n },\n });\n this.producer = this.kafka.producer({\n kafkaJS: {\n acks: -1,\n },\n });\n this.admin = this.kafka.admin();\n }\n\n // ── Send ─────────────────────────────────────────────────────────\n\n /** Send a single typed message. Accepts a topic key or a TopicDescriptor. */\n public async sendMessage<\n D extends TopicDescriptor<string & keyof T, T[string & keyof T]>,\n >(descriptor: D, message: D[\"__type\"], options?: SendOptions): Promise<void>;\n public async sendMessage<K extends keyof T>(\n topic: K,\n message: T[K],\n options?: SendOptions,\n ): Promise<void>;\n public async sendMessage(\n topicOrDesc: any,\n message: any,\n options: SendOptions = {},\n ): Promise<void> {\n const payload = await this.buildSendPayload(topicOrDesc, [\n {\n value: message,\n key: options.key,\n headers: options.headers,\n correlationId: options.correlationId,\n schemaVersion: options.schemaVersion,\n eventId: options.eventId,\n },\n ]);\n await this.ensureTopic(payload.topic);\n await this.producer.send(payload);\n for (const inst of this.instrumentation) {\n inst.afterSend?.(payload.topic);\n }\n }\n\n /** Send multiple typed messages in one call. Accepts a topic key or a TopicDescriptor. */\n public async sendBatch<\n D extends TopicDescriptor<string & keyof T, T[string & keyof T]>,\n >(\n descriptor: D,\n messages: Array<BatchMessageItem<D[\"__type\"]>>,\n ): Promise<void>;\n public async sendBatch<K extends keyof T>(\n topic: K,\n messages: Array<BatchMessageItem<T[K]>>,\n ): Promise<void>;\n public async sendBatch(\n topicOrDesc: any,\n messages: Array<BatchMessageItem<any>>,\n ): Promise<void> {\n const payload = await this.buildSendPayload(topicOrDesc, messages);\n await this.ensureTopic(payload.topic);\n await this.producer.send(payload);\n for (const inst of this.instrumentation) {\n inst.afterSend?.(payload.topic);\n }\n }\n\n /** Execute multiple sends atomically. Commits on success, aborts on error. */\n public async transaction(\n fn: (ctx: TransactionContext<T>) => Promise<void>,\n ): Promise<void> {\n if (!this.txProducer) {\n this.txProducer = this.kafka.producer({\n kafkaJS: {\n acks: -1,\n idempotent: true,\n transactionalId: `${this.clientId}-tx`,\n maxInFlightRequests: 1,\n },\n });\n await this.txProducer.connect();\n }\n const tx = await this.txProducer.transaction();\n try {\n const ctx: TransactionContext<T> = {\n send: async (\n topicOrDesc: any,\n message: any,\n options: SendOptions = {},\n ) => {\n const payload = await this.buildSendPayload(topicOrDesc, [\n {\n value: message,\n key: options.key,\n headers: options.headers,\n correlationId: options.correlationId,\n schemaVersion: options.schemaVersion,\n eventId: options.eventId,\n },\n ]);\n await this.ensureTopic(payload.topic);\n await tx.send(payload);\n },\n sendBatch: async (topicOrDesc: any, messages: BatchMessageItem<any>[]) => {\n const payload = await this.buildSendPayload(topicOrDesc, messages);\n await this.ensureTopic(payload.topic);\n await tx.send(payload);\n },\n };\n await fn(ctx);\n await tx.commit();\n } catch (error) {\n try {\n await tx.abort();\n } catch (abortError) {\n this.logger.error(\n \"Failed to abort transaction:\",\n toError(abortError).message,\n );\n }\n throw error;\n }\n }\n\n // ── Producer lifecycle ───────────────────────────────────────────\n\n /** Connect the idempotent producer. Called automatically by `KafkaModule.register()`. */\n public async connectProducer(): Promise<void> {\n await this.producer.connect();\n this.logger.log(\"Producer connected\");\n }\n\n public async disconnectProducer(): Promise<void> {\n await this.producer.disconnect();\n this.logger.log(\"Producer disconnected\");\n }\n\n // ── Consumer: eachMessage ────────────────────────────────────────\n\n /** Subscribe to topics and start consuming messages with the given handler. */\n public async startConsumer<K extends Array<keyof T>>(\n topics: K,\n handleMessage: (envelope: EventEnvelope<T[K[number]]>) => Promise<void>,\n options?: ConsumerOptions<T>,\n ): Promise<void>;\n public async startConsumer<\n D extends TopicDescriptor<string & keyof T, T[string & keyof T]>,\n >(\n topics: D[],\n handleMessage: (envelope: EventEnvelope<D[\"__type\"]>) => Promise<void>,\n options?: ConsumerOptions<T>,\n ): Promise<void>;\n public async startConsumer(\n topics: any[],\n handleMessage: (envelope: EventEnvelope<any>) => Promise<void>,\n options: ConsumerOptions<T> = {},\n ): Promise<void> {\n const { consumer, schemaMap, gid, dlq, interceptors, retry } =\n await this.setupConsumer(topics, \"eachMessage\", options);\n\n const deps = { logger: this.logger, producer: this.producer, instrumentation: this.instrumentation, onMessageLost: this.onMessageLost };\n\n await consumer.run({\n eachMessage: async ({ topic, partition, message }) => {\n if (!message.value) {\n this.logger.warn(`Received empty message from topic ${topic}`);\n return;\n }\n\n const raw = message.value.toString();\n const parsed = parseJsonMessage(raw, topic, this.logger);\n if (parsed === null) return;\n\n const headers = decodeHeaders(message.headers);\n const validated = await validateWithSchema(\n parsed, raw, topic, schemaMap, interceptors, dlq,\n { ...deps, originalHeaders: headers },\n );\n if (validated === null) return;\n\n const envelope = extractEnvelope(\n validated, headers, topic, partition, message.offset,\n );\n\n await executeWithRetry(\n () =>\n runWithEnvelopeContext(\n { correlationId: envelope.correlationId, traceparent: envelope.traceparent },\n () => handleMessage(envelope),\n ),\n { envelope, rawMessages: [raw], interceptors, dlq, retry },\n deps,\n );\n },\n });\n\n this.runningConsumers.set(gid, \"eachMessage\");\n }\n\n // ── Consumer: eachBatch ──────────────────────────────────────────\n\n /** Subscribe to topics and consume messages in batches. */\n public async startBatchConsumer<K extends Array<keyof T>>(\n topics: K,\n handleBatch: (\n envelopes: EventEnvelope<T[K[number]]>[],\n meta: BatchMeta,\n ) => Promise<void>,\n options?: ConsumerOptions<T>,\n ): Promise<void>;\n public async startBatchConsumer<\n D extends TopicDescriptor<string & keyof T, T[string & keyof T]>,\n >(\n topics: D[],\n handleBatch: (\n envelopes: EventEnvelope<D[\"__type\"]>[],\n meta: BatchMeta,\n ) => Promise<void>,\n options?: ConsumerOptions<T>,\n ): Promise<void>;\n public async startBatchConsumer(\n topics: any[],\n handleBatch: (\n envelopes: EventEnvelope<any>[],\n meta: BatchMeta,\n ) => Promise<void>,\n options: ConsumerOptions<T> = {},\n ): Promise<void> {\n const { consumer, schemaMap, gid, dlq, interceptors, retry } =\n await this.setupConsumer(topics, \"eachBatch\", options);\n\n const deps = { logger: this.logger, producer: this.producer, instrumentation: this.instrumentation, onMessageLost: this.onMessageLost };\n\n await consumer.run({\n eachBatch: async ({\n batch,\n heartbeat,\n resolveOffset,\n commitOffsetsIfNecessary,\n }) => {\n const envelopes: EventEnvelope<any>[] = [];\n const rawMessages: string[] = [];\n\n for (const message of batch.messages) {\n if (!message.value) {\n this.logger.warn(\n `Received empty message from topic ${batch.topic}`,\n );\n continue;\n }\n\n const raw = message.value.toString();\n const parsed = parseJsonMessage(raw, batch.topic, this.logger);\n if (parsed === null) continue;\n\n const headers = decodeHeaders(message.headers);\n const validated = await validateWithSchema(\n parsed, raw, batch.topic, schemaMap, interceptors, dlq,\n { ...deps, originalHeaders: headers },\n );\n if (validated === null) continue;\n envelopes.push(\n extractEnvelope(validated, headers, batch.topic, batch.partition, message.offset),\n );\n rawMessages.push(raw);\n }\n\n if (envelopes.length === 0) return;\n\n const meta: BatchMeta = {\n partition: batch.partition,\n highWatermark: batch.highWatermark,\n heartbeat,\n resolveOffset,\n commitOffsetsIfNecessary,\n };\n\n await executeWithRetry(\n () => handleBatch(envelopes, meta),\n {\n envelope: envelopes,\n rawMessages: batch.messages\n .filter((m) => m.value)\n .map((m) => m.value!.toString()),\n interceptors,\n dlq,\n retry,\n isBatch: true,\n },\n deps,\n );\n },\n });\n\n this.runningConsumers.set(gid, \"eachBatch\");\n }\n\n // ── Consumer lifecycle ───────────────────────────────────────────\n\n public async stopConsumer(): Promise<void> {\n const tasks = [];\n for (const consumer of this.consumers.values()) {\n tasks.push(consumer.disconnect());\n }\n await Promise.allSettled(tasks);\n this.consumers.clear();\n this.runningConsumers.clear();\n this.logger.log(\"All consumers disconnected\");\n }\n\n /** Check broker connectivity and return status, clientId, and available topics. */\n public async checkStatus(): Promise<{ status: 'up'; clientId: string; topics: string[] }> {\n if (!this.isAdminConnected) {\n await this.admin.connect();\n this.isAdminConnected = true;\n }\n const topics = await this.admin.listTopics();\n return { status: 'up', clientId: this.clientId, topics };\n }\n\n public getClientId(): ClientId {\n return this.clientId;\n }\n\n /** Gracefully disconnect producer, all consumers, and admin. */\n public async disconnect(): Promise<void> {\n const tasks: Promise<void>[] = [this.producer.disconnect()];\n if (this.txProducer) {\n tasks.push(this.txProducer.disconnect());\n this.txProducer = undefined;\n }\n for (const consumer of this.consumers.values()) {\n tasks.push(consumer.disconnect());\n }\n if (this.isAdminConnected) {\n tasks.push(this.admin.disconnect());\n this.isAdminConnected = false;\n }\n await Promise.allSettled(tasks);\n this.consumers.clear();\n this.runningConsumers.clear();\n this.logger.log(\"All connections closed\");\n }\n\n // ── Private helpers ──────────────────────────────────────────────\n\n private getOrCreateConsumer(\n groupId: string,\n fromBeginning: boolean,\n autoCommit: boolean,\n ): Consumer {\n if (!this.consumers.has(groupId)) {\n this.consumers.set(\n groupId,\n this.kafka.consumer({\n kafkaJS: { groupId, fromBeginning, autoCommit },\n }),\n );\n }\n return this.consumers.get(groupId)!;\n }\n\n private resolveTopicName(topicOrDescriptor: unknown): string {\n if (typeof topicOrDescriptor === \"string\") return topicOrDescriptor;\n if (\n topicOrDescriptor &&\n typeof topicOrDescriptor === \"object\" &&\n \"__topic\" in topicOrDescriptor\n ) {\n return (topicOrDescriptor as TopicDescriptor).__topic;\n }\n return String(topicOrDescriptor);\n }\n\n private async ensureTopic(topic: string): Promise<void> {\n if (!this.autoCreateTopicsEnabled || this.ensuredTopics.has(topic)) return;\n if (!this.isAdminConnected) {\n await this.admin.connect();\n this.isAdminConnected = true;\n }\n await this.admin.createTopics({\n topics: [{ topic, numPartitions: this.numPartitions }],\n });\n this.ensuredTopics.add(topic);\n }\n\n /** Register schema from descriptor into global registry (side-effect). */\n private registerSchema(topicOrDesc: any): void {\n if (topicOrDesc?.__schema) {\n const topic = this.resolveTopicName(topicOrDesc);\n this.schemaRegistry.set(topic, topicOrDesc.__schema);\n }\n }\n\n /** Validate message against schema. Pure — no side-effects on registry. */\n private async validateMessage(topicOrDesc: any, message: any): Promise<any> {\n if (topicOrDesc?.__schema) {\n return await topicOrDesc.__schema.parse(message);\n }\n if (this.strictSchemasEnabled && typeof topicOrDesc === \"string\") {\n const schema = this.schemaRegistry.get(topicOrDesc);\n if (schema) return await schema.parse(message);\n }\n return message;\n }\n\n /**\n * Build a kafkajs-ready send payload.\n * Handles: topic resolution, schema registration, validation, JSON serialization,\n * envelope header generation, and instrumentation hooks.\n */\n private async buildSendPayload(\n topicOrDesc: any,\n messages: Array<BatchMessageItem<any>>,\n ): Promise<{ topic: string; messages: Array<{ value: string; key: string | null; headers: MessageHeaders }> }> {\n this.registerSchema(topicOrDesc);\n const topic = this.resolveTopicName(topicOrDesc);\n const builtMessages = await Promise.all(\n messages.map(async (m) => {\n const envelopeHeaders = buildEnvelopeHeaders({\n correlationId: m.correlationId,\n schemaVersion: m.schemaVersion,\n eventId: m.eventId,\n headers: m.headers,\n });\n\n // Let instrumentation hooks mutate headers (e.g. OTel injects traceparent)\n for (const inst of this.instrumentation) {\n inst.beforeSend?.(topic, envelopeHeaders);\n }\n\n return {\n value: JSON.stringify(await this.validateMessage(topicOrDesc, m.value)),\n key: m.key ?? null,\n headers: envelopeHeaders,\n };\n }),\n );\n return { topic, messages: builtMessages };\n }\n\n /** Shared consumer setup: groupId check, schema map, connect, subscribe. */\n private async setupConsumer(\n topics: any[],\n mode: \"eachMessage\" | \"eachBatch\",\n options: ConsumerOptions<T>,\n ) {\n const {\n groupId: optGroupId,\n fromBeginning = false,\n retry,\n dlq = false,\n interceptors = [],\n schemas: optionSchemas,\n } = options;\n\n const gid = optGroupId || this.defaultGroupId;\n const existingMode = this.runningConsumers.get(gid);\n const oppositeMode = mode === \"eachMessage\" ? \"eachBatch\" : \"eachMessage\";\n if (existingMode === oppositeMode) {\n throw new Error(\n `Cannot use ${mode} on consumer group \"${gid}\" — it is already running with ${oppositeMode}. ` +\n `Use a different groupId for this consumer.`,\n );\n }\n\n const consumer = this.getOrCreateConsumer(gid, fromBeginning, options.autoCommit ?? true);\n const schemaMap = this.buildSchemaMap(topics, optionSchemas);\n\n const topicNames = (topics as any[]).map((t: any) =>\n this.resolveTopicName(t),\n );\n\n // Ensure topics exist before subscribing — librdkafka errors on unknown topics\n for (const t of topicNames) {\n await this.ensureTopic(t);\n }\n if (dlq) {\n for (const t of topicNames) {\n await this.ensureTopic(`${t}.dlq`);\n }\n }\n\n await consumer.connect();\n await subscribeWithRetry(consumer, topicNames, this.logger, options.subscribeRetry);\n\n this.logger.log(\n `${mode === \"eachBatch\" ? \"Batch consumer\" : \"Consumer\"} subscribed to topics: ${topicNames.join(\", \")}`,\n );\n\n return { consumer, schemaMap, topicNames, gid, dlq, interceptors, retry };\n }\n\n private buildSchemaMap(\n topics: any[],\n optionSchemas?: Map<string, SchemaLike>,\n ): Map<string, SchemaLike> {\n const schemaMap = new Map<string, SchemaLike>();\n for (const t of topics) {\n if (t?.__schema) {\n const name = this.resolveTopicName(t);\n schemaMap.set(name, t.__schema);\n this.schemaRegistry.set(name, t.__schema);\n }\n }\n if (optionSchemas) {\n for (const [k, v] of optionSchemas) {\n schemaMap.set(k, v);\n this.schemaRegistry.set(k, v);\n }\n }\n return schemaMap;\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { randomUUID } from \"node:crypto\";\nimport type { MessageHeaders } from \"./types\";\n\n// ── Header keys ──────────────────────────────────────────────────────\n\nexport const HEADER_EVENT_ID = \"x-event-id\";\nexport const HEADER_CORRELATION_ID = \"x-correlation-id\";\nexport const HEADER_TIMESTAMP = \"x-timestamp\";\nexport const HEADER_SCHEMA_VERSION = \"x-schema-version\";\nexport const HEADER_TRACEPARENT = \"traceparent\";\n\n// ── EventEnvelope ────────────────────────────────────────────────────\n\n/**\n * Typed wrapper combining a parsed message payload with Kafka metadata\n * and envelope headers.\n *\n * On **send**, the library auto-generates envelope headers\n * (`x-event-id`, `x-correlation-id`, `x-timestamp`, `x-schema-version`).\n *\n * On **consume**, the library extracts those headers and assembles\n * an `EventEnvelope` that is passed to the handler.\n */\nexport interface EventEnvelope<T> {\n /** Deserialized + validated message body. */\n payload: T;\n /** Topic the message was produced to / consumed from. */\n topic: string;\n /** Kafka partition (consume-side only, `-1` on send). */\n partition: number;\n /** Kafka offset (consume-side only, empty string on send). */\n offset: string;\n /** ISO-8601 timestamp set by the producer. */\n timestamp: string;\n /** Unique ID for this event (UUID v4). */\n eventId: string;\n /** Correlation ID — auto-propagated via AsyncLocalStorage. */\n correlationId: string;\n /** Schema version of the payload. */\n schemaVersion: number;\n /** W3C Trace Context `traceparent` header (set by OTel instrumentation). */\n traceparent?: string;\n /** All decoded Kafka headers for extensibility. */\n headers: MessageHeaders;\n}\n\n// ── AsyncLocalStorage context ────────────────────────────────────────\n\ninterface EnvelopeCtx {\n correlationId: string;\n traceparent?: string;\n}\n\nconst envelopeStorage = new AsyncLocalStorage<EnvelopeCtx>();\n\n/** Read the current envelope context (correlationId / traceparent) from ALS. */\nexport function getEnvelopeContext(): EnvelopeCtx | undefined {\n return envelopeStorage.getStore();\n}\n\n/** Execute `fn` inside an envelope context so nested sends inherit correlationId. */\nexport function runWithEnvelopeContext<R>(\n ctx: EnvelopeCtx,\n fn: () => R,\n): R {\n return envelopeStorage.run(ctx, fn);\n}\n\n// ── Header helpers ───────────────────────────────────────────────────\n\n/** Options accepted by `buildEnvelopeHeaders`. */\nexport interface EnvelopeHeaderOptions {\n correlationId?: string;\n schemaVersion?: number;\n eventId?: string;\n headers?: MessageHeaders;\n}\n\n/**\n * Generate envelope headers for the send path.\n *\n * Priority for `correlationId`:\n * explicit option → ALS context → new UUID.\n */\nexport function buildEnvelopeHeaders(\n options: EnvelopeHeaderOptions = {},\n): MessageHeaders {\n const ctx = getEnvelopeContext();\n\n const correlationId =\n options.correlationId ?? ctx?.correlationId ?? randomUUID();\n const eventId = options.eventId ?? randomUUID();\n const timestamp = new Date().toISOString();\n const schemaVersion = String(options.schemaVersion ?? 1);\n\n const envelope: MessageHeaders = {\n [HEADER_EVENT_ID]: eventId,\n [HEADER_CORRELATION_ID]: correlationId,\n [HEADER_TIMESTAMP]: timestamp,\n [HEADER_SCHEMA_VERSION]: schemaVersion,\n };\n\n // Propagate traceparent from ALS if present (OTel may override via instrumentation)\n if (ctx?.traceparent) {\n envelope[HEADER_TRACEPARENT] = ctx.traceparent;\n }\n\n // User-provided headers win on conflict\n return { ...envelope, ...options.headers };\n}\n\n/**\n * Decode kafkajs headers (`Record<string, Buffer | string | undefined>`)\n * into plain `Record<string, string>`.\n */\nexport function decodeHeaders(\n raw: Record<string, Buffer | string | (Buffer | string)[] | undefined> | undefined,\n): MessageHeaders {\n if (!raw) return {};\n const result: MessageHeaders = {};\n for (const [key, value] of Object.entries(raw)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n result[key] = value.map((v) => (Buffer.isBuffer(v) ? v.toString() : v)).join(\",\");\n } else {\n result[key] = Buffer.isBuffer(value) ? value.toString() : value;\n }\n }\n return result;\n}\n\n/**\n * Build an `EventEnvelope` from a consumed kafkajs message.\n * Tolerates missing envelope headers — generates defaults so messages\n * from non-envelope producers still work.\n */\nexport function extractEnvelope<T>(\n payload: T,\n headers: MessageHeaders,\n topic: string,\n partition: number,\n offset: string,\n): EventEnvelope<T> {\n return {\n payload,\n topic,\n partition,\n offset,\n eventId: headers[HEADER_EVENT_ID] ?? randomUUID(),\n correlationId: headers[HEADER_CORRELATION_ID] ?? randomUUID(),\n timestamp: headers[HEADER_TIMESTAMP] ?? new Date().toISOString(),\n schemaVersion: Number(headers[HEADER_SCHEMA_VERSION] ?? 1),\n traceparent: headers[HEADER_TRACEPARENT],\n headers,\n };\n}\n","/** Error thrown when a consumer message handler fails. */\nexport class KafkaProcessingError extends Error {\n declare readonly cause?: Error;\n\n constructor(\n message: string,\n public readonly topic: string,\n public readonly originalMessage: unknown,\n options?: { cause?: Error },\n ) {\n super(message, options);\n this.name = \"KafkaProcessingError\";\n if (options?.cause) this.cause = options.cause;\n }\n}\n\n/** Error thrown when schema validation fails on send or consume. */\nexport class KafkaValidationError extends Error {\n declare readonly cause?: Error;\n\n constructor(\n public readonly topic: string,\n public readonly originalMessage: unknown,\n options?: { cause?: Error },\n ) {\n super(`Schema validation failed for topic \"${topic}\"`, options);\n this.name = \"KafkaValidationError\";\n if (options?.cause) this.cause = options.cause;\n }\n}\n\n/** Error thrown when all retry attempts are exhausted for a message. */\nexport class KafkaRetryExhaustedError extends KafkaProcessingError {\n constructor(\n topic: string,\n originalMessage: unknown,\n public readonly attempts: number,\n options?: { cause?: Error },\n ) {\n super(\n `Message processing failed after ${attempts} attempts on topic \"${topic}\"`,\n topic,\n originalMessage,\n options,\n );\n this.name = \"KafkaRetryExhaustedError\";\n }\n}\n","import type { KafkaJS } from \"@confluentinc/kafka-javascript\";\ntype Producer = KafkaJS.Producer;\nimport type { EventEnvelope } from \"./envelope\";\nimport { extractEnvelope } from \"./envelope\";\nimport { KafkaRetryExhaustedError, KafkaValidationError } from \"./errors\";\nimport type { SchemaLike } from \"./topic\";\nimport type {\n ConsumerInterceptor,\n KafkaInstrumentation,\n KafkaLogger,\n MessageHeaders,\n MessageLostContext,\n RetryOptions,\n TopicMapConstraint,\n} from \"./types\";\n\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nexport function toError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ── JSON parsing ────────────────────────────────────────────────────\n\n/** Parse raw message as JSON. Returns null on failure (logs error). */\nexport function parseJsonMessage(\n raw: string,\n topic: string,\n logger: KafkaLogger,\n): any | null {\n try {\n return JSON.parse(raw);\n } catch (error) {\n logger.error(\n `Failed to parse message from topic ${topic}:`,\n toError(error).stack,\n );\n return null;\n }\n}\n\n// ── Schema validation ───────────────────────────────────────────────\n\n/**\n * Validate a parsed message against the schema map.\n * On failure: logs error, sends to DLQ if enabled, calls interceptor.onError.\n * Returns validated message or null.\n */\nexport async function validateWithSchema<T extends TopicMapConstraint<T>>(\n message: any,\n raw: string,\n topic: string,\n schemaMap: Map<string, SchemaLike>,\n interceptors: ConsumerInterceptor<T>[],\n dlq: boolean,\n deps: {\n logger: KafkaLogger;\n producer: Producer;\n onMessageLost?: (ctx: MessageLostContext) => void | Promise<void>;\n originalHeaders?: MessageHeaders;\n },\n): Promise<any | null> {\n const schema = schemaMap.get(topic);\n if (!schema) return message;\n\n try {\n return await schema.parse(message);\n } catch (error) {\n const err = toError(error);\n const validationError = new KafkaValidationError(topic, message, {\n cause: err,\n });\n deps.logger.error(\n `Schema validation failed for topic ${topic}:`,\n err.message,\n );\n if (dlq) {\n await sendToDlq(topic, raw, deps, {\n error: validationError,\n attempt: 0,\n originalHeaders: deps.originalHeaders,\n });\n } else {\n await deps.onMessageLost?.({ topic, error: validationError, attempt: 0, headers: deps.originalHeaders ?? {} });\n }\n // Validation errors don't have an envelope yet — call onError with a minimal envelope\n const errorEnvelope = extractEnvelope(message, deps.originalHeaders ?? {}, topic, -1, \"\");\n for (const interceptor of interceptors) {\n await interceptor.onError?.(errorEnvelope, validationError);\n }\n return null;\n }\n}\n\n// ── DLQ ─────────────────────────────────────────────────────────────\n\nexport interface DlqMetadata {\n error: Error;\n attempt: number;\n /** Original Kafka message headers — forwarded to DLQ to preserve correlationId, traceparent, etc. */\n originalHeaders?: MessageHeaders;\n}\n\nexport async function sendToDlq(\n topic: string,\n rawMessage: string,\n deps: { logger: KafkaLogger; producer: Producer },\n meta?: DlqMetadata,\n): Promise<void> {\n const dlqTopic = `${topic}.dlq`;\n const headers: MessageHeaders = {\n ...(meta?.originalHeaders ?? {}),\n 'x-dlq-original-topic': topic,\n 'x-dlq-failed-at': new Date().toISOString(),\n 'x-dlq-error-message': meta?.error.message ?? 'unknown',\n 'x-dlq-error-stack': meta?.error.stack?.slice(0, 2000) ?? '',\n 'x-dlq-attempt-count': String(meta?.attempt ?? 0),\n };\n try {\n await deps.producer.send({\n topic: dlqTopic,\n messages: [{ value: rawMessage, headers }],\n });\n deps.logger.warn(`Message sent to DLQ: ${dlqTopic}`);\n } catch (error) {\n deps.logger.error(\n `Failed to send message to DLQ ${dlqTopic}:`,\n toError(error).stack,\n );\n }\n}\n\n// ── Retry pipeline ──────────────────────────────────────────────────\n\nexport interface ExecuteWithRetryContext<T extends TopicMapConstraint<T>> {\n envelope: EventEnvelope<any> | EventEnvelope<any>[];\n rawMessages: string[];\n interceptors: ConsumerInterceptor<T>[];\n dlq: boolean;\n retry?: RetryOptions;\n isBatch?: boolean;\n}\n\n/**\n * Execute a handler with retry, interceptors, instrumentation, and DLQ support.\n * Used by both single-message and batch consumers.\n */\nexport async function executeWithRetry<T extends TopicMapConstraint<T>>(\n fn: () => Promise<void>,\n ctx: ExecuteWithRetryContext<T>,\n deps: {\n logger: KafkaLogger;\n producer: Producer;\n instrumentation: KafkaInstrumentation[];\n onMessageLost?: (ctx: MessageLostContext) => void | Promise<void>;\n },\n): Promise<void> {\n const { envelope, rawMessages, interceptors, dlq, retry, isBatch } = ctx;\n const maxAttempts = retry ? retry.maxRetries + 1 : 1;\n const backoffMs = retry?.backoffMs ?? 1000;\n const maxBackoffMs = retry?.maxBackoffMs ?? 30_000;\n const envelopes = Array.isArray(envelope) ? envelope : [envelope];\n const topic = envelopes[0]?.topic ?? \"unknown\";\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n // Collect instrumentation cleanup functions\n const cleanups: (() => void)[] = [];\n\n try {\n // Instrumentation: beforeConsume\n for (const env of envelopes) {\n for (const inst of deps.instrumentation) {\n const cleanup = inst.beforeConsume?.(env);\n if (typeof cleanup === \"function\") cleanups.push(cleanup);\n }\n }\n\n // Consumer interceptors: before\n for (const env of envelopes) {\n for (const interceptor of interceptors) {\n await interceptor.before?.(env);\n }\n }\n\n await fn();\n\n // Consumer interceptors: after\n for (const env of envelopes) {\n for (const interceptor of interceptors) {\n await interceptor.after?.(env);\n }\n }\n\n // Instrumentation: cleanup (end spans etc.)\n for (const cleanup of cleanups) cleanup();\n\n return;\n } catch (error) {\n const err = toError(error);\n const isLastAttempt = attempt === maxAttempts;\n\n // Instrumentation: onConsumeError\n for (const env of envelopes) {\n for (const inst of deps.instrumentation) {\n inst.onConsumeError?.(env, err);\n }\n }\n // Instrumentation: cleanup even on error\n for (const cleanup of cleanups) cleanup();\n\n if (isLastAttempt && maxAttempts > 1) {\n const exhaustedError = new KafkaRetryExhaustedError(\n topic,\n envelopes.map((e) => e.payload),\n maxAttempts,\n { cause: err },\n );\n for (const env of envelopes) {\n for (const interceptor of interceptors) {\n await interceptor.onError?.(env, exhaustedError);\n }\n }\n } else {\n for (const env of envelopes) {\n for (const interceptor of interceptors) {\n await interceptor.onError?.(env, err);\n }\n }\n }\n\n deps.logger.error(\n `Error processing ${isBatch ? \"batch\" : \"message\"} from topic ${topic} (attempt ${attempt}/${maxAttempts}):`,\n err.stack,\n );\n\n if (isLastAttempt) {\n if (dlq) {\n const dlqMeta: DlqMetadata = {\n error: err,\n attempt,\n originalHeaders: envelopes[0]?.headers,\n };\n for (const raw of rawMessages) {\n await sendToDlq(topic, raw, deps, dlqMeta);\n }\n } else {\n await deps.onMessageLost?.({\n topic,\n error: err,\n attempt,\n headers: envelopes[0]?.headers ?? {},\n });\n }\n } else {\n // Exponential backoff with full jitter to avoid thundering herd\n const cap = Math.min(backoffMs * 2 ** (attempt - 1), maxBackoffMs);\n await sleep(Math.random() * cap);\n }\n }\n }\n}\n","import type { KafkaJS } from \"@confluentinc/kafka-javascript\";\nimport type { KafkaLogger, SubscribeRetryOptions } from \"./types\";\nimport { toError, sleep } from \"./consumer-pipeline\";\n\nexport async function subscribeWithRetry(\n consumer: KafkaJS.Consumer,\n topics: string[],\n logger: KafkaLogger,\n retryOpts?: SubscribeRetryOptions,\n): Promise<void> {\n const maxAttempts = retryOpts?.retries ?? 5;\n const backoffMs = retryOpts?.backoffMs ?? 5000;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n await consumer.subscribe({ topics });\n return;\n } catch (error) {\n if (attempt === maxAttempts) throw error;\n const msg = toError(error).message;\n logger.warn(\n `Failed to subscribe to [${topics.join(\", \")}] (attempt ${attempt}/${maxAttempts}): ${msg}. Retrying in ${backoffMs}ms...`,\n );\n await sleep(backoffMs);\n }\n }\n}\n","/**\n * Any validation library with a `.parse()` method.\n * Works with Zod, Valibot, ArkType, or any custom validator.\n *\n * @example\n * ```ts\n * import { z } from 'zod';\n * const schema: SchemaLike<{ id: string }> = z.object({ id: z.string() });\n * ```\n */\nexport interface SchemaLike<T = any> {\n parse(data: unknown): T | Promise<T>;\n}\n\n/** Infer the output type from a SchemaLike. */\nexport type InferSchema<S extends SchemaLike> =\n S extends SchemaLike<infer T> ? T : never;\n\n/**\n * A typed topic descriptor that pairs a topic name with its message type.\n * Created via the `topic()` factory function.\n *\n * @typeParam N - The literal topic name string.\n * @typeParam M - The message payload type for this topic.\n */\nexport interface TopicDescriptor<\n N extends string = string,\n M extends Record<string, any> = Record<string, any>,\n> {\n readonly __topic: N;\n /** @internal Phantom type — never has a real value at runtime. */\n readonly __type: M;\n /** Runtime schema validator. Present only when created via `topic().schema()`. */\n readonly __schema?: SchemaLike<M>;\n}\n\n/**\n * Define a typed topic descriptor.\n *\n * @example\n * ```ts\n * // Without schema — type provided explicitly:\n * const OrderCreated = topic('order.created')<{ orderId: string; amount: number }>();\n *\n * // With schema — type inferred from schema:\n * const OrderCreated = topic('order.created').schema(z.object({\n * orderId: z.string(),\n * amount: z.number(),\n * }));\n *\n * // Use with KafkaClient:\n * await kafka.sendMessage(OrderCreated, { orderId: '123', amount: 100 });\n *\n * // Use with @SubscribeTo:\n * @SubscribeTo(OrderCreated)\n * async handleOrder(msg) { ... }\n * ```\n */\nexport function topic<N extends string>(name: N) {\n const fn = <M extends Record<string, any>>(): TopicDescriptor<N, M> => ({\n __topic: name,\n __type: undefined as unknown as M,\n });\n\n fn.schema = <S extends SchemaLike<Record<string, any>>>(\n schema: S,\n ): TopicDescriptor<N, InferSchema<S>> => ({\n __topic: name,\n __type: undefined as unknown as InferSchema<S>,\n __schema: schema as unknown as SchemaLike<InferSchema<S>>,\n });\n\n return fn;\n}\n\n/**\n * Build a topic-message map type from a union of TopicDescriptors.\n *\n * @example\n * ```ts\n * const OrderCreated = topic('order.created')<{ orderId: string }>();\n * const OrderCompleted = topic('order.completed')<{ completedAt: string }>();\n *\n * type MyTopics = TopicsFrom<typeof OrderCreated | typeof OrderCompleted>;\n * // { 'order.created': { orderId: string }; 'order.completed': { completedAt: string } }\n * ```\n */\nexport type TopicsFrom<D extends TopicDescriptor<any, any>> = {\n [K in D as K[\"__topic\"]]: K[\"__type\"];\n};\n"],"mappings":"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","names":["topic","topic","topic","topic"]}
|
package/dist/core.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as TopicMapConstraint, I as IKafkaClient, C as ClientId, G as GroupId, k as KafkaClientOptions, b as TopicDescriptor,
|
|
2
|
-
export { d as ConsumerInterceptor, E as EnvelopeHeaderOptions, H as HEADER_CORRELATION_ID, f as HEADER_EVENT_ID, g as HEADER_SCHEMA_VERSION, h as HEADER_TIMESTAMP, i as HEADER_TRACEPARENT, j as InferSchema, K as KafkaInstrumentation, l as KafkaLogger, M as MessageHeaders, R as RetryOptions, S as SchemaLike,
|
|
1
|
+
import { T as TopicMapConstraint, I as IKafkaClient, C as ClientId, G as GroupId, k as KafkaClientOptions, b as TopicDescriptor, n as SendOptions, B as BatchMessageItem, r as TransactionContext, e as EventEnvelope, a as ConsumerOptions, c as BatchMeta } from './envelope-C66_h8r_.mjs';
|
|
2
|
+
export { d as ConsumerInterceptor, E as EnvelopeHeaderOptions, H as HEADER_CORRELATION_ID, f as HEADER_EVENT_ID, g as HEADER_SCHEMA_VERSION, h as HEADER_TIMESTAMP, i as HEADER_TRACEPARENT, j as InferSchema, K as KafkaInstrumentation, l as KafkaLogger, M as MessageHeaders, m as MessageLostContext, R as RetryOptions, S as SchemaLike, o as SubscribeRetryOptions, p as TTopicMessageMap, q as TopicsFrom, s as buildEnvelopeHeaders, t as decodeHeaders, u as extractEnvelope, v as getEnvelopeContext, w as runWithEnvelopeContext, x as topic } from './envelope-C66_h8r_.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Type-safe Kafka client.
|
|
@@ -23,6 +23,7 @@ declare class KafkaClient<T extends TopicMapConstraint<T>> implements IKafkaClie
|
|
|
23
23
|
private readonly schemaRegistry;
|
|
24
24
|
private readonly runningConsumers;
|
|
25
25
|
private readonly instrumentation;
|
|
26
|
+
private readonly onMessageLost;
|
|
26
27
|
private isAdminConnected;
|
|
27
28
|
readonly clientId: ClientId;
|
|
28
29
|
constructor(clientId: ClientId, groupId: GroupId, brokers: string[], options?: KafkaClientOptions);
|
package/dist/core.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as TopicMapConstraint, I as IKafkaClient, C as ClientId, G as GroupId, k as KafkaClientOptions, b as TopicDescriptor,
|
|
2
|
-
export { d as ConsumerInterceptor, E as EnvelopeHeaderOptions, H as HEADER_CORRELATION_ID, f as HEADER_EVENT_ID, g as HEADER_SCHEMA_VERSION, h as HEADER_TIMESTAMP, i as HEADER_TRACEPARENT, j as InferSchema, K as KafkaInstrumentation, l as KafkaLogger, M as MessageHeaders, R as RetryOptions, S as SchemaLike,
|
|
1
|
+
import { T as TopicMapConstraint, I as IKafkaClient, C as ClientId, G as GroupId, k as KafkaClientOptions, b as TopicDescriptor, n as SendOptions, B as BatchMessageItem, r as TransactionContext, e as EventEnvelope, a as ConsumerOptions, c as BatchMeta } from './envelope-C66_h8r_.js';
|
|
2
|
+
export { d as ConsumerInterceptor, E as EnvelopeHeaderOptions, H as HEADER_CORRELATION_ID, f as HEADER_EVENT_ID, g as HEADER_SCHEMA_VERSION, h as HEADER_TIMESTAMP, i as HEADER_TRACEPARENT, j as InferSchema, K as KafkaInstrumentation, l as KafkaLogger, M as MessageHeaders, m as MessageLostContext, R as RetryOptions, S as SchemaLike, o as SubscribeRetryOptions, p as TTopicMessageMap, q as TopicsFrom, s as buildEnvelopeHeaders, t as decodeHeaders, u as extractEnvelope, v as getEnvelopeContext, w as runWithEnvelopeContext, x as topic } from './envelope-C66_h8r_.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Type-safe Kafka client.
|
|
@@ -23,6 +23,7 @@ declare class KafkaClient<T extends TopicMapConstraint<T>> implements IKafkaClie
|
|
|
23
23
|
private readonly schemaRegistry;
|
|
24
24
|
private readonly runningConsumers;
|
|
25
25
|
private readonly instrumentation;
|
|
26
|
+
private readonly onMessageLost;
|
|
26
27
|
private isAdminConnected;
|
|
27
28
|
readonly clientId: ClientId;
|
|
28
29
|
constructor(clientId: ClientId, groupId: GroupId, brokers: string[], options?: KafkaClientOptions);
|