@drarzter/kafka-client 0.9.4 → 0.11.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 +693 -8
- package/dist/chunk-OR7TPAAE.mjs +4760 -0
- package/dist/chunk-OR7TPAAE.mjs.map +1 -0
- package/dist/chunk-PQVBRDNV.mjs +149 -0
- package/dist/chunk-PQVBRDNV.mjs.map +1 -0
- package/dist/cli/dlq.d.ts +119 -0
- package/dist/cli/dlq.d.ts.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/{chunk-SM4FZKAZ.mjs → cli/index.js} +1073 -309
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +356 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/client/config/from-env.d.ts +188 -0
- package/dist/client/config/from-env.d.ts.map +1 -0
- package/dist/client/config/index.d.ts +2 -0
- package/dist/client/config/index.d.ts.map +1 -0
- package/dist/client/errors.d.ts +67 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/kafka.client/admin/ops.d.ts +114 -0
- package/dist/client/kafka.client/admin/ops.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/features/delayed.d.ts +24 -0
- package/dist/client/kafka.client/consumer/features/delayed.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/features/dlq-replay.d.ts +52 -0
- package/dist/client/kafka.client/consumer/features/dlq-replay.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/features/routed.d.ts +4 -0
- package/dist/client/kafka.client/consumer/features/routed.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/features/snapshot.d.ts +10 -0
- package/dist/client/kafka.client/consumer/features/snapshot.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/features/window.d.ts +5 -0
- package/dist/client/kafka.client/consumer/features/window.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/handler.d.ts +163 -0
- package/dist/client/kafka.client/consumer/handler.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/ops.d.ts +64 -0
- package/dist/client/kafka.client/consumer/ops.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/pipeline.d.ts +168 -0
- package/dist/client/kafka.client/consumer/pipeline.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/queue.d.ts +37 -0
- package/dist/client/kafka.client/consumer/queue.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/retry-topic.d.ts +68 -0
- package/dist/client/kafka.client/consumer/retry-topic.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/setup.d.ts +66 -0
- package/dist/client/kafka.client/consumer/setup.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/start.d.ts +7 -0
- package/dist/client/kafka.client/consumer/start.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/stop.d.ts +19 -0
- package/dist/client/kafka.client/consumer/stop.d.ts.map +1 -0
- package/dist/client/kafka.client/consumer/subscribe-retry.d.ts +4 -0
- package/dist/client/kafka.client/consumer/subscribe-retry.d.ts.map +1 -0
- package/dist/client/kafka.client/context.d.ts +75 -0
- package/dist/client/kafka.client/context.d.ts.map +1 -0
- package/dist/client/kafka.client/index.d.ts +155 -0
- package/dist/client/kafka.client/index.d.ts.map +1 -0
- package/dist/client/kafka.client/infra/circuit-breaker.manager.d.ts +61 -0
- package/dist/client/kafka.client/infra/circuit-breaker.manager.d.ts.map +1 -0
- package/dist/client/kafka.client/infra/dedup.store.d.ts +28 -0
- package/dist/client/kafka.client/infra/dedup.store.d.ts.map +1 -0
- package/dist/client/kafka.client/infra/inflight.tracker.d.ts +22 -0
- package/dist/client/kafka.client/infra/inflight.tracker.d.ts.map +1 -0
- package/dist/client/kafka.client/infra/metrics.manager.d.ts +67 -0
- package/dist/client/kafka.client/infra/metrics.manager.d.ts.map +1 -0
- package/dist/client/kafka.client/producer/lifecycle.d.ts +41 -0
- package/dist/client/kafka.client/producer/lifecycle.d.ts.map +1 -0
- package/dist/client/kafka.client/producer/ops.d.ts +79 -0
- package/dist/client/kafka.client/producer/ops.d.ts.map +1 -0
- package/dist/client/kafka.client/producer/send.d.ts +21 -0
- package/dist/client/kafka.client/producer/send.d.ts.map +1 -0
- package/dist/client/kafka.client/validate-options.d.ts +11 -0
- package/dist/client/kafka.client/validate-options.d.ts.map +1 -0
- package/dist/client/message/envelope.d.ts +105 -0
- package/dist/client/message/envelope.d.ts.map +1 -0
- package/dist/client/message/schema-registry.d.ts +124 -0
- package/dist/client/message/schema-registry.d.ts.map +1 -0
- package/dist/client/message/serde.d.ts +68 -0
- package/dist/client/message/serde.d.ts.map +1 -0
- package/dist/client/message/topic.d.ts +159 -0
- package/dist/client/message/topic.d.ts.map +1 -0
- package/dist/client/message/versioned-schema.d.ts +53 -0
- package/dist/client/message/versioned-schema.d.ts.map +1 -0
- package/dist/client/outbox/index.d.ts +4 -0
- package/dist/client/outbox/index.d.ts.map +1 -0
- package/dist/client/outbox/outbox.relay.d.ts +90 -0
- package/dist/client/outbox/outbox.relay.d.ts.map +1 -0
- package/dist/client/outbox/outbox.store.d.ts +42 -0
- package/dist/client/outbox/outbox.store.d.ts.map +1 -0
- package/dist/client/outbox/outbox.types.d.ts +144 -0
- package/dist/client/outbox/outbox.types.d.ts.map +1 -0
- package/dist/client/security/acl.d.ts +108 -0
- package/dist/client/security/acl.d.ts.map +1 -0
- package/dist/client/security/index.d.ts +5 -0
- package/dist/client/security/index.d.ts.map +1 -0
- package/dist/client/security/providers.d.ts +88 -0
- package/dist/client/security/providers.d.ts.map +1 -0
- package/dist/client/security/resolve-security.d.ts +19 -0
- package/dist/client/security/resolve-security.d.ts.map +1 -0
- package/dist/client/security/security.types.d.ts +76 -0
- package/dist/client/security/security.types.d.ts.map +1 -0
- package/dist/client/transport/confluent.transport.d.ts +32 -0
- package/dist/client/transport/confluent.transport.d.ts.map +1 -0
- package/dist/client/transport/transport.interface.d.ts +221 -0
- package/dist/client/transport/transport.interface.d.ts.map +1 -0
- package/dist/client/types/admin.interface.d.ts +174 -0
- package/dist/client/types/admin.interface.d.ts.map +1 -0
- package/dist/client/types/admin.types.d.ts +140 -0
- package/dist/client/types/admin.types.d.ts.map +1 -0
- package/dist/client/types/client.d.ts +21 -0
- package/dist/client/types/client.d.ts.map +1 -0
- package/dist/client/types/common.d.ts +84 -0
- package/dist/client/types/common.d.ts.map +1 -0
- package/dist/client/types/config.types.d.ts +167 -0
- package/dist/client/types/config.types.d.ts.map +1 -0
- package/dist/client/types/consumer.interface.d.ts +115 -0
- package/dist/client/types/consumer.interface.d.ts.map +1 -0
- package/dist/{consumer.types-fFCag3VJ.d.mts → client/types/consumer.types.d.ts} +62 -383
- package/dist/client/types/consumer.types.d.ts.map +1 -0
- package/dist/client/types/dedup.types.d.ts +50 -0
- package/dist/client/types/dedup.types.d.ts.map +1 -0
- package/dist/client/types/lifecycle.interface.d.ts +72 -0
- package/dist/client/types/lifecycle.interface.d.ts.map +1 -0
- package/dist/client/types/producer.interface.d.ts +52 -0
- package/dist/client/types/producer.interface.d.ts.map +1 -0
- package/dist/client/types/producer.types.d.ts +90 -0
- package/dist/client/types/producer.types.d.ts.map +1 -0
- package/dist/client/types.d.ts +8 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/core.d.ts +13 -314
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +1466 -123
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +45 -3
- package/dist/index.d.ts +7 -128
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1483 -123
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -3
- package/dist/index.mjs.map +1 -1
- package/dist/nest/kafka.constants.d.ts +5 -0
- package/dist/nest/kafka.constants.d.ts.map +1 -0
- package/dist/nest/kafka.decorator.d.ts +49 -0
- package/dist/nest/kafka.decorator.d.ts.map +1 -0
- package/dist/nest/kafka.explorer.d.ts +17 -0
- package/dist/nest/kafka.explorer.d.ts.map +1 -0
- package/dist/nest/kafka.health.d.ts +7 -0
- package/dist/nest/kafka.health.d.ts.map +1 -0
- package/dist/nest/kafka.module.d.ts +61 -0
- package/dist/nest/kafka.module.d.ts.map +1 -0
- package/dist/otel.d.ts +83 -5
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +100 -6
- package/dist/otel.js.map +1 -1
- package/dist/otel.mjs +98 -5
- package/dist/otel.mjs.map +1 -1
- package/dist/serde.d.ts +157 -0
- package/dist/serde.d.ts.map +1 -0
- package/dist/serde.js +308 -0
- package/dist/serde.js.map +1 -0
- package/dist/serde.mjs +158 -0
- package/dist/serde.mjs.map +1 -0
- package/dist/testing/client.mock.d.ts +47 -0
- package/dist/testing/client.mock.d.ts.map +1 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/test.container.d.ts +63 -0
- package/dist/testing/test.container.d.ts.map +1 -0
- package/dist/{testing.d.mts → testing/transport.fake.d.ts} +7 -111
- package/dist/testing/transport.fake.d.ts.map +1 -0
- package/dist/testing.d.ts +2 -318
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +26 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +26 -0
- package/dist/testing.mjs.map +1 -1
- package/package.json +40 -8
- package/dist/chunk-SM4FZKAZ.mjs.map +0 -1
- package/dist/client-1irhGEu0.d.mts +0 -751
- package/dist/client-BpFjkHhr.d.ts +0 -751
- package/dist/consumer.types-fFCag3VJ.d.ts +0 -958
- package/dist/core.d.mts +0 -314
- package/dist/index.d.mts +0 -128
- package/dist/otel.d.mts +0 -27
|
@@ -1,359 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* ```ts
|
|
7
|
-
* // with explicit extends (IDE hints for values)
|
|
8
|
-
* interface MyTopics extends TTopicMessageMap {
|
|
9
|
-
* "orders.created": { orderId: string; amount: number };
|
|
10
|
-
* "users.updated": { userId: string; name: string };
|
|
11
|
-
* }
|
|
12
|
-
*
|
|
13
|
-
* // or plain interface / type — works the same
|
|
14
|
-
* interface MyTopics {
|
|
15
|
-
* "orders.created": { orderId: string; amount: number };
|
|
16
|
-
* }
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
type TTopicMessageMap = {
|
|
20
|
-
[topic: string]: Record<string, any>;
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* Generic constraint for topic-message maps.
|
|
24
|
-
* Works with both `type` aliases and `interface` declarations.
|
|
25
|
-
*/
|
|
26
|
-
type TopicMapConstraint<T> = {
|
|
27
|
-
[K in keyof T]: Record<string, any>;
|
|
28
|
-
};
|
|
29
|
-
type ClientId = string;
|
|
30
|
-
type GroupId = string;
|
|
31
|
-
type MessageHeaders = Record<string, string>;
|
|
32
|
-
/**
|
|
33
|
-
* Message compression codec.
|
|
34
|
-
* Maps directly to the underlying librdkafka codec values.
|
|
35
|
-
* - `'none'` — no compression (default)
|
|
36
|
-
* - `'gzip'` — widely supported, moderate compression ratio
|
|
37
|
-
* - `'snappy'` — fast, moderate compression ratio
|
|
38
|
-
* - `'lz4'` — fastest, slightly lower ratio
|
|
39
|
-
* - `'zstd'` — best ratio, slightly slower
|
|
40
|
-
*/
|
|
41
|
-
type CompressionType = "none" | "gzip" | "snappy" | "lz4" | "zstd";
|
|
42
|
-
/**
|
|
43
|
-
* Logger interface for KafkaClient.
|
|
44
|
-
* Compatible with NestJS Logger, console, winston, pino, or any custom logger.
|
|
45
|
-
*
|
|
46
|
-
* `debug` is optional — omit it to suppress debug output in production.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```ts
|
|
50
|
-
* // Pass a NestJS logger:
|
|
51
|
-
* const kafka = new KafkaClient(config, groupId, { logger: this.logger });
|
|
52
|
-
*
|
|
53
|
-
* // Or a minimal pino wrapper:
|
|
54
|
-
* const kafka = new KafkaClient(config, groupId, {
|
|
55
|
-
* logger: {
|
|
56
|
-
* log: (msg) => pino.info(msg),
|
|
57
|
-
* warn: (msg, ...a) => pino.warn(msg, ...a),
|
|
58
|
-
* error: (msg, ...a) => pino.error(msg, ...a),
|
|
59
|
-
* debug: (msg, ...a) => pino.debug(msg, ...a),
|
|
60
|
-
* },
|
|
61
|
-
* });
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
interface KafkaLogger {
|
|
65
|
-
log(message: string): void;
|
|
66
|
-
warn(message: string, ...args: any[]): void;
|
|
67
|
-
error(message: string, ...args: any[]): void;
|
|
68
|
-
debug?(message: string, ...args: any[]): void;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Snapshot of internal event counters accumulated since client creation
|
|
72
|
-
* (or since the last `resetMetrics()` call).
|
|
73
|
-
*/
|
|
74
|
-
interface KafkaMetrics {
|
|
75
|
-
/** Total messages successfully processed by the consumer handler. */
|
|
76
|
-
processedCount: number;
|
|
77
|
-
/** Total retry attempts routed — covers both in-process retries and retry-topic hops. */
|
|
78
|
-
retryCount: number;
|
|
79
|
-
/** Total messages sent to a DLQ topic. */
|
|
80
|
-
dlqCount: number;
|
|
81
|
-
/** Total duplicate messages detected by the Lamport clock. */
|
|
82
|
-
dedupCount: number;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Options for sending a single message.
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```ts
|
|
90
|
-
* await kafka.sendMessage('orders.created', { orderId: '123', amount: 99 }, {
|
|
91
|
-
* key: 'order-123',
|
|
92
|
-
* headers: { 'x-source': 'checkout-service' },
|
|
93
|
-
* compression: 'snappy',
|
|
94
|
-
* });
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
interface SendOptions {
|
|
98
|
-
/** Partition key for message routing. */
|
|
99
|
-
key?: string;
|
|
100
|
-
/** Custom headers attached to the message (merged with auto-generated envelope headers). */
|
|
101
|
-
headers?: MessageHeaders;
|
|
102
|
-
/** Override the auto-propagated correlation ID (default: inherited from ALS context or new UUID). */
|
|
103
|
-
correlationId?: string;
|
|
104
|
-
/** Schema version for the payload. Default: `1`. */
|
|
105
|
-
schemaVersion?: number;
|
|
106
|
-
/** Override the auto-generated event ID (UUID v4). */
|
|
107
|
-
eventId?: string;
|
|
108
|
-
/**
|
|
109
|
-
* Compression codec for this message.
|
|
110
|
-
* Applied at the producer record level — all messages in a single `send` call share the same codec.
|
|
111
|
-
* Default: `'none'`.
|
|
112
|
-
*/
|
|
113
|
-
compression?: CompressionType;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Shape of each item in a `sendBatch` call.
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```ts
|
|
120
|
-
* await kafka.sendBatch('orders.created', [
|
|
121
|
-
* { value: { orderId: '1', amount: 10 }, key: 'order-1' },
|
|
122
|
-
* { value: { orderId: '2', amount: 20 }, key: 'order-2', headers: { 'x-priority': 'high' } },
|
|
123
|
-
* ]);
|
|
124
|
-
* ```
|
|
125
|
-
*/
|
|
126
|
-
interface BatchMessageItem<V> {
|
|
127
|
-
value: V;
|
|
128
|
-
/**
|
|
129
|
-
* Kafka partition key for this message.
|
|
130
|
-
* Kafka hashes the key to deterministically route the message to a partition.
|
|
131
|
-
* Messages with the same key always land on the same partition — use this to
|
|
132
|
-
* guarantee ordering per entity (e.g. `userId`, `orderId`).
|
|
133
|
-
*/
|
|
134
|
-
key?: string;
|
|
135
|
-
headers?: MessageHeaders;
|
|
136
|
-
correlationId?: string;
|
|
137
|
-
schemaVersion?: number;
|
|
138
|
-
eventId?: string;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Options for a `sendBatch` call (applies to all messages in the batch).
|
|
142
|
-
*
|
|
143
|
-
* @example
|
|
144
|
-
* ```ts
|
|
145
|
-
* await kafka.sendBatch('metrics', messages, { compression: 'zstd' });
|
|
146
|
-
* ```
|
|
147
|
-
*/
|
|
148
|
-
interface BatchSendOptions {
|
|
149
|
-
/**
|
|
150
|
-
* Compression codec for this batch.
|
|
151
|
-
* Applied at the producer record level — all messages in the batch share the same codec.
|
|
152
|
-
* Default: `'none'`.
|
|
153
|
-
*/
|
|
154
|
-
compression?: CompressionType;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Context passed as the second argument to `SchemaLike.parse()`.
|
|
159
|
-
* Enables schema-registry adapters, version-aware migration, and
|
|
160
|
-
* header-driven parsing without coupling validators to Kafka internals.
|
|
161
|
-
*
|
|
162
|
-
* All fields are optional-friendly — validators that don't need the context
|
|
163
|
-
* can simply ignore the second argument.
|
|
164
|
-
*/
|
|
165
|
-
interface SchemaParseContext {
|
|
166
|
-
/** Topic the message was produced to / consumed from. */
|
|
167
|
-
topic: string;
|
|
168
|
-
/** Decoded message headers (envelope headers included). */
|
|
169
|
-
headers: MessageHeaders;
|
|
170
|
-
/** Value of the `x-schema-version` header, defaults to `1`. */
|
|
171
|
-
version: number;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Any validation library with a `.parse()` method.
|
|
175
|
-
* Works with Zod, Valibot, ArkType, or any custom validator.
|
|
176
|
-
*
|
|
177
|
-
* The optional `ctx` argument carries topic/header/version metadata so
|
|
178
|
-
* validators can perform schema-registry lookups or version-aware migrations.
|
|
179
|
-
* Existing validators that only use the first argument continue to work
|
|
180
|
-
* unchanged — the second argument is silently ignored.
|
|
181
|
-
*
|
|
182
|
-
* @example
|
|
183
|
-
* ```ts
|
|
184
|
-
* import { z } from 'zod';
|
|
185
|
-
* const schema: SchemaLike<{ id: string }> = z.object({ id: z.string() });
|
|
186
|
-
*
|
|
187
|
-
* // Context-aware validator:
|
|
188
|
-
* const schema: SchemaLike<MyType> = {
|
|
189
|
-
* parse(data, ctx) {
|
|
190
|
-
* const version = ctx?.version ?? 1;
|
|
191
|
-
* return version >= 2 ? migrateV1toV2(data) : validateV1(data);
|
|
192
|
-
* }
|
|
193
|
-
* };
|
|
194
|
-
* ```
|
|
195
|
-
*/
|
|
196
|
-
interface SchemaLike<T = any> {
|
|
197
|
-
parse(data: unknown, ctx?: SchemaParseContext): T | Promise<T>;
|
|
198
|
-
}
|
|
199
|
-
/** Infer the output type from a SchemaLike. */
|
|
200
|
-
type InferSchema<S extends SchemaLike> = S extends SchemaLike<infer T> ? T : never;
|
|
201
|
-
/**
|
|
202
|
-
* A typed topic descriptor that pairs a topic name with its message type.
|
|
203
|
-
* Created via the `topic()` factory function.
|
|
204
|
-
*
|
|
205
|
-
* @typeParam N - The literal topic name string.
|
|
206
|
-
* @typeParam M - The message payload type for this topic.
|
|
207
|
-
*/
|
|
208
|
-
interface TopicDescriptor<N extends string = string, M extends Record<string, any> = Record<string, any>> {
|
|
209
|
-
readonly __topic: N;
|
|
210
|
-
/** @internal Phantom type — never has a real value at runtime. */
|
|
211
|
-
readonly __type: M;
|
|
212
|
-
/** Runtime schema validator. Present only when created via `topic().schema()`. */
|
|
213
|
-
readonly __schema?: SchemaLike<M>;
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Define a typed topic descriptor.
|
|
217
|
-
*
|
|
218
|
-
* @example
|
|
219
|
-
* ```ts
|
|
220
|
-
* // Without schema — explicit type via .type<T>():
|
|
221
|
-
* const OrderCreated = topic('order.created').type<{ orderId: string; amount: number }>();
|
|
222
|
-
*
|
|
223
|
-
* // With schema — type inferred from schema:
|
|
224
|
-
* const OrderCreated = topic('order.created').schema(z.object({
|
|
225
|
-
* orderId: z.string(),
|
|
226
|
-
* amount: z.number(),
|
|
227
|
-
* }));
|
|
228
|
-
*
|
|
229
|
-
* // Use with KafkaClient:
|
|
230
|
-
* await kafka.sendMessage(OrderCreated, { orderId: '123', amount: 100 });
|
|
231
|
-
*
|
|
232
|
-
* // Use with @SubscribeTo:
|
|
233
|
-
* @SubscribeTo(OrderCreated)
|
|
234
|
-
* async handleOrder(msg) { ... }
|
|
235
|
-
* ```
|
|
236
|
-
*/
|
|
237
|
-
declare function topic<N extends string>(name: N): {
|
|
238
|
-
/** Provide an explicit message type without a runtime schema. */
|
|
239
|
-
type: <M extends Record<string, any>>() => TopicDescriptor<N, M>;
|
|
240
|
-
schema: <S extends SchemaLike<Record<string, any>>>(schema: S) => TopicDescriptor<N, InferSchema<S>>;
|
|
241
|
-
};
|
|
242
|
-
/**
|
|
243
|
-
* Build a topic-message map type from a union of TopicDescriptors.
|
|
244
|
-
*
|
|
245
|
-
* @example
|
|
246
|
-
* ```ts
|
|
247
|
-
* const OrderCreated = topic('order.created').type<{ orderId: string }>();
|
|
248
|
-
* const OrderCompleted = topic('order.completed').type<{ completedAt: string }>();
|
|
249
|
-
*
|
|
250
|
-
* type MyTopics = TopicsFrom<typeof OrderCreated | typeof OrderCompleted>;
|
|
251
|
-
* // { 'order.created': { orderId: string }; 'order.completed': { completedAt: string } }
|
|
252
|
-
* ```
|
|
253
|
-
*/
|
|
254
|
-
type TopicsFrom<D extends TopicDescriptor<any, any>> = {
|
|
255
|
-
[K in D as K["__topic"]]: K["__type"];
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
declare const HEADER_EVENT_ID = "x-event-id";
|
|
259
|
-
declare const HEADER_CORRELATION_ID = "x-correlation-id";
|
|
260
|
-
declare const HEADER_TIMESTAMP = "x-timestamp";
|
|
261
|
-
declare const HEADER_SCHEMA_VERSION = "x-schema-version";
|
|
262
|
-
declare const HEADER_TRACEPARENT = "traceparent";
|
|
263
|
-
/** Monotonically increasing logical clock stamped by the producer for deduplication. */
|
|
264
|
-
declare const HEADER_LAMPORT_CLOCK = "x-lamport-clock";
|
|
265
|
-
/**
|
|
266
|
-
* Typed wrapper combining a parsed message payload with Kafka metadata
|
|
267
|
-
* and envelope headers.
|
|
268
|
-
*
|
|
269
|
-
* On **send**, the library auto-generates envelope headers
|
|
270
|
-
* (`x-event-id`, `x-correlation-id`, `x-timestamp`, `x-schema-version`).
|
|
271
|
-
*
|
|
272
|
-
* On **consume**, the library extracts those headers and assembles
|
|
273
|
-
* an `EventEnvelope` that is passed to the handler.
|
|
274
|
-
*
|
|
275
|
-
* @example
|
|
276
|
-
* ```ts
|
|
277
|
-
* await kafka.startConsumer(['orders'], async (envelope: EventEnvelope<Order>) => {
|
|
278
|
-
* console.log(envelope.payload.orderId); // typed payload
|
|
279
|
-
* console.log(envelope.correlationId); // auto-propagated
|
|
280
|
-
* console.log(envelope.eventId); // unique message ID
|
|
281
|
-
* });
|
|
282
|
-
* ```
|
|
283
|
-
*/
|
|
284
|
-
interface EventEnvelope<T> {
|
|
285
|
-
/** Deserialized + validated message body. */
|
|
286
|
-
payload: T;
|
|
287
|
-
/** Topic the message was produced to / consumed from. */
|
|
288
|
-
topic: string;
|
|
289
|
-
/** Kafka partition (consume-side only, `-1` on send). */
|
|
290
|
-
partition: number;
|
|
291
|
-
/** Kafka offset (consume-side only, empty string on send). */
|
|
292
|
-
offset: string;
|
|
293
|
-
/** ISO-8601 timestamp set by the producer. */
|
|
294
|
-
timestamp: string;
|
|
295
|
-
/** Unique ID for this event (UUID v4). */
|
|
296
|
-
eventId: string;
|
|
297
|
-
/** Correlation ID — auto-propagated via AsyncLocalStorage. */
|
|
298
|
-
correlationId: string;
|
|
299
|
-
/** Schema version of the payload. */
|
|
300
|
-
schemaVersion: number;
|
|
301
|
-
/** W3C Trace Context `traceparent` header (set by OTel instrumentation). */
|
|
302
|
-
traceparent?: string;
|
|
303
|
-
/** All decoded Kafka headers for extensibility. */
|
|
304
|
-
headers: MessageHeaders;
|
|
305
|
-
}
|
|
306
|
-
interface EnvelopeCtx {
|
|
307
|
-
correlationId: string;
|
|
308
|
-
traceparent?: string;
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Read the current envelope context (correlationId / traceparent) from ALS.
|
|
312
|
-
* Returns `undefined` outside of a Kafka consumer handler.
|
|
313
|
-
* @example
|
|
314
|
-
* ```ts
|
|
315
|
-
* const ctx = getEnvelopeContext();
|
|
316
|
-
* if (ctx) console.log('correlationId:', ctx.correlationId);
|
|
317
|
-
* ```
|
|
318
|
-
*/
|
|
319
|
-
declare function getEnvelopeContext(): EnvelopeCtx | undefined;
|
|
320
|
-
/**
|
|
321
|
-
* Execute `fn` inside an envelope context so nested sends inherit correlationId.
|
|
322
|
-
* Automatically called by the consumer pipeline — use this in tests or manual flows.
|
|
323
|
-
* @example
|
|
324
|
-
* ```ts
|
|
325
|
-
* await runWithEnvelopeContext({ correlationId: 'abc-123' }, async () => {
|
|
326
|
-
* await kafka.sendMessage('orders.created', payload); // inherits correlationId
|
|
327
|
-
* });
|
|
328
|
-
* ```
|
|
329
|
-
*/
|
|
330
|
-
declare function runWithEnvelopeContext<R>(ctx: EnvelopeCtx, fn: () => R): R;
|
|
331
|
-
/** Options accepted by `buildEnvelopeHeaders`. */
|
|
332
|
-
interface EnvelopeHeaderOptions {
|
|
333
|
-
correlationId?: string;
|
|
334
|
-
schemaVersion?: number;
|
|
335
|
-
eventId?: string;
|
|
336
|
-
headers?: MessageHeaders;
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Generate envelope headers for the send path.
|
|
340
|
-
*
|
|
341
|
-
* Priority for `correlationId`:
|
|
342
|
-
* explicit option → ALS context → new UUID.
|
|
343
|
-
*/
|
|
344
|
-
declare function buildEnvelopeHeaders(options?: EnvelopeHeaderOptions): MessageHeaders;
|
|
345
|
-
/**
|
|
346
|
-
* Decode kafkajs headers (`Record<string, Buffer | string | undefined>`)
|
|
347
|
-
* into plain `Record<string, string>`.
|
|
348
|
-
*/
|
|
349
|
-
declare function decodeHeaders(raw: Record<string, Buffer | string | (Buffer | string)[] | undefined> | undefined): MessageHeaders;
|
|
350
|
-
/**
|
|
351
|
-
* Build an `EventEnvelope` from a consumed kafkajs message.
|
|
352
|
-
* Tolerates missing envelope headers — generates defaults so messages
|
|
353
|
-
* from non-envelope producers still work.
|
|
354
|
-
*/
|
|
355
|
-
declare function extractEnvelope<T>(payload: T, headers: MessageHeaders, topic: string, partition: number, offset: string): EventEnvelope<T>;
|
|
356
|
-
|
|
1
|
+
import type { TTopicMessageMap, TopicMapConstraint, MessageHeaders } from "./common";
|
|
2
|
+
import type { SendOptions, BatchMessageItem, BatchSendOptions } from "./producer.types";
|
|
3
|
+
import type { DedupStore } from "./dedup.types";
|
|
4
|
+
import type { TopicDescriptor, SchemaLike } from "../message/topic";
|
|
5
|
+
import type { EventEnvelope } from "../message/envelope";
|
|
357
6
|
/**
|
|
358
7
|
* Metadata exposed to batch consumer handlers.
|
|
359
8
|
*
|
|
@@ -367,7 +16,7 @@ declare function extractEnvelope<T>(payload: T, headers: MessageHeaders, topic:
|
|
|
367
16
|
* }, { autoCommit: false });
|
|
368
17
|
* ```
|
|
369
18
|
*/
|
|
370
|
-
interface BatchMeta {
|
|
19
|
+
export interface BatchMeta {
|
|
371
20
|
/** Partition number for this batch. */
|
|
372
21
|
partition: number;
|
|
373
22
|
/**
|
|
@@ -394,7 +43,7 @@ interface BatchMeta {
|
|
|
394
43
|
* });
|
|
395
44
|
* ```
|
|
396
45
|
*/
|
|
397
|
-
interface RetryOptions {
|
|
46
|
+
export interface RetryOptions {
|
|
398
47
|
/** Maximum number of retry attempts before giving up. */
|
|
399
48
|
maxRetries: number;
|
|
400
49
|
/** Base delay for exponential backoff in ms. Default: `1000`. */
|
|
@@ -421,15 +70,15 @@ interface RetryOptions {
|
|
|
421
70
|
* Messages that arrive without the `x-lamport-clock` header are passed through
|
|
422
71
|
* unchanged (backwards-compatible with producers that don't use this library).
|
|
423
72
|
*
|
|
424
|
-
* **In-session limitation**:
|
|
425
|
-
* whenever the process restarts or `stopConsumer`
|
|
426
|
-
* previously processed messages with `clock ≤ N`
|
|
427
|
-
* their offsets catch up to the high-watermark again.
|
|
428
|
-
* rebalance: the instance that receives the partition
|
|
429
|
-
*
|
|
430
|
-
*
|
|
73
|
+
* **In-session limitation (default store)**: with the built-in in-memory store,
|
|
74
|
+
* deduplication state is reset whenever the process restarts or `stopConsumer`
|
|
75
|
+
* is called. After a restart, previously processed messages with `clock ≤ N`
|
|
76
|
+
* will be re-processed until their offsets catch up to the high-watermark again.
|
|
77
|
+
* The same applies after a rebalance: the instance that receives the partition
|
|
78
|
+
* begins with empty state. Provide a persistent `store` (e.g. Redis-backed) to
|
|
79
|
+
* make deduplication survive both restarts and rebalances.
|
|
431
80
|
*/
|
|
432
|
-
interface DeduplicationOptions {
|
|
81
|
+
export interface DeduplicationOptions {
|
|
433
82
|
/**
|
|
434
83
|
* What to do with detected duplicate messages:
|
|
435
84
|
* - `'drop'` — silently discard. No routing, no callback. **(default)**
|
|
@@ -443,6 +92,18 @@ interface DeduplicationOptions {
|
|
|
443
92
|
* Defaults to `<consumedTopic>.duplicates`.
|
|
444
93
|
*/
|
|
445
94
|
duplicatesTopic?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Pluggable backing store for the per-partition last-processed clock.
|
|
97
|
+
*
|
|
98
|
+
* When omitted, an in-memory store is used — state is per-client, keyed by
|
|
99
|
+
* `groupId`, and cleared on `stopConsumer` / `disconnect`. Provide a
|
|
100
|
+
* persistent `DedupStore` (e.g. Redis-backed) so deduplication survives
|
|
101
|
+
* process restarts and consumer group rebalances.
|
|
102
|
+
*
|
|
103
|
+
* Store errors are handled fail-open: on a thrown/rejected read or write the
|
|
104
|
+
* error is logged and the message is treated as not a duplicate.
|
|
105
|
+
*/
|
|
106
|
+
store?: DedupStore;
|
|
446
107
|
}
|
|
447
108
|
/**
|
|
448
109
|
* Options for the per-partition circuit breaker.
|
|
@@ -469,7 +130,7 @@ interface DeduplicationOptions {
|
|
|
469
130
|
* - **HALF-OPEN** — the partition is resumed. If the next `halfOpenSuccesses` messages
|
|
470
131
|
* succeed the circuit closes; a new failure immediately re-opens it.
|
|
471
132
|
*/
|
|
472
|
-
interface CircuitBreakerOptions {
|
|
133
|
+
export interface CircuitBreakerOptions {
|
|
473
134
|
/**
|
|
474
135
|
* Number of failures within the sliding window required to open the circuit.
|
|
475
136
|
* A failure is any message that ends up in the DLQ.
|
|
@@ -510,7 +171,7 @@ interface CircuitBreakerOptions {
|
|
|
510
171
|
* await kafka.startConsumer(['orders'], handler, { interceptors: [logger] });
|
|
511
172
|
* ```
|
|
512
173
|
*/
|
|
513
|
-
interface ConsumerInterceptor<T extends TopicMapConstraint<T> = TTopicMessageMap> {
|
|
174
|
+
export interface ConsumerInterceptor<T extends TopicMapConstraint<T> = TTopicMessageMap> {
|
|
514
175
|
/** Called before the message handler. */
|
|
515
176
|
before?(envelope: EventEnvelope<T[keyof T]>): Promise<void> | void;
|
|
516
177
|
/** Called after the message handler succeeds. */
|
|
@@ -548,7 +209,7 @@ interface ConsumerInterceptor<T extends TopicMapConstraint<T> = TTopicMessageMap
|
|
|
548
209
|
* }
|
|
549
210
|
* ```
|
|
550
211
|
*/
|
|
551
|
-
type BeforeConsumeResult = (() => void) | {
|
|
212
|
+
export type BeforeConsumeResult = (() => void) | {
|
|
552
213
|
cleanup?(): void;
|
|
553
214
|
wrap?(fn: () => Promise<void>): Promise<void>;
|
|
554
215
|
};
|
|
@@ -560,7 +221,7 @@ type BeforeConsumeResult = (() => void) | {
|
|
|
560
221
|
* and `deduplication.strategy` is `'dlq'`.
|
|
561
222
|
* - `'ttl-expired'` — message age exceeded `messageTtlMs` before the handler ran.
|
|
562
223
|
*/
|
|
563
|
-
type DlqReason = "handler-error" | "validation-error" | "lamport-clock-duplicate" | "ttl-expired";
|
|
224
|
+
export type DlqReason = "handler-error" | "validation-error" | "lamport-clock-duplicate" | "ttl-expired";
|
|
564
225
|
/**
|
|
565
226
|
* Client-wide instrumentation hooks for both send and consume paths.
|
|
566
227
|
* Use this for cross-cutting concerns like tracing and metrics.
|
|
@@ -585,7 +246,7 @@ type DlqReason = "handler-error" | "validation-error" | "lamport-clock-duplicate
|
|
|
585
246
|
* const kafka = new KafkaClient(config, groupId, { instrumentation: [tracing] });
|
|
586
247
|
* ```
|
|
587
248
|
*/
|
|
588
|
-
interface KafkaInstrumentation {
|
|
249
|
+
export interface KafkaInstrumentation {
|
|
589
250
|
/** Called before sending — can mutate `headers` (e.g. inject `traceparent`). */
|
|
590
251
|
beforeSend?(topic: string, headers: MessageHeaders): void;
|
|
591
252
|
/** Called after a successful send. */
|
|
@@ -638,7 +299,7 @@ interface KafkaInstrumentation {
|
|
|
638
299
|
* });
|
|
639
300
|
* ```
|
|
640
301
|
*/
|
|
641
|
-
interface TtlExpiredContext {
|
|
302
|
+
export interface TtlExpiredContext {
|
|
642
303
|
/** Topic the message was consumed from. */
|
|
643
304
|
topic: string;
|
|
644
305
|
/** Actual age of the message in ms at the time it was dropped. */
|
|
@@ -661,7 +322,7 @@ interface TtlExpiredContext {
|
|
|
661
322
|
* });
|
|
662
323
|
* ```
|
|
663
324
|
*/
|
|
664
|
-
interface MessageLostContext {
|
|
325
|
+
export interface MessageLostContext {
|
|
665
326
|
/** Topic the message was consumed from. */
|
|
666
327
|
topic: string;
|
|
667
328
|
/** Error that caused the message to be dropped. */
|
|
@@ -681,7 +342,7 @@ interface MessageLostContext {
|
|
|
681
342
|
* });
|
|
682
343
|
* ```
|
|
683
344
|
*/
|
|
684
|
-
interface SubscribeRetryOptions {
|
|
345
|
+
export interface SubscribeRetryOptions {
|
|
685
346
|
/** Maximum number of subscribe attempts. Default: `5`. */
|
|
686
347
|
retries?: number;
|
|
687
348
|
/** Delay between retries in ms. Default: `5000`. */
|
|
@@ -702,7 +363,7 @@ interface SubscribeRetryOptions {
|
|
|
702
363
|
* });
|
|
703
364
|
* ```
|
|
704
365
|
*/
|
|
705
|
-
interface ConsumerOptions<T extends TopicMapConstraint<T> = TTopicMessageMap> {
|
|
366
|
+
export interface ConsumerOptions<T extends TopicMapConstraint<T> = TTopicMessageMap> {
|
|
706
367
|
/** Override the default consumer group ID from the constructor. */
|
|
707
368
|
groupId?: string;
|
|
708
369
|
/** Start reading from earliest offset. Default: `false`. */
|
|
@@ -779,6 +440,25 @@ interface ConsumerOptions<T extends TopicMapConstraint<T> = TTopicMessageMap> {
|
|
|
779
440
|
* - `'range'` — assigns contiguous partition ranges; can cause uneven distribution with multiple topics.
|
|
780
441
|
*/
|
|
781
442
|
partitionAssigner?: "roundrobin" | "range" | "cooperative-sticky";
|
|
443
|
+
/**
|
|
444
|
+
* Static group membership id (`group.instance.id`).
|
|
445
|
+
*
|
|
446
|
+
* A member that restarts within the broker's `session.timeout.ms` rejoins
|
|
447
|
+
* the group with the same partitions and **no rebalance** — useful for k8s
|
|
448
|
+
* rolling restarts and short redeploys. Must be unique per member within
|
|
449
|
+
* the consumer group (e.g. derive from the pod ordinal / hostname).
|
|
450
|
+
*
|
|
451
|
+
* Not propagated to retry-chain companion consumers (they run in their own
|
|
452
|
+
* groups and rebalance independently).
|
|
453
|
+
*
|
|
454
|
+
* @example
|
|
455
|
+
* ```ts
|
|
456
|
+
* await kafka.startConsumer(['orders'], handler, {
|
|
457
|
+
* groupInstanceId: `orders-svc-${process.env.HOSTNAME}`,
|
|
458
|
+
* });
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
groupInstanceId?: string;
|
|
782
462
|
/**
|
|
783
463
|
* Called when a message is dropped due to TTL expiration (`messageTtlMs`).
|
|
784
464
|
* Fires instead of `onMessageLost` for expired messages when `dlq` is not enabled.
|
|
@@ -814,7 +494,7 @@ interface ConsumerOptions<T extends TopicMapConstraint<T> = TTopicMessageMap> {
|
|
|
814
494
|
* await handle.stop();
|
|
815
495
|
* ```
|
|
816
496
|
*/
|
|
817
|
-
interface ConsumerHandle {
|
|
497
|
+
export interface ConsumerHandle {
|
|
818
498
|
/** The consumer group ID this consumer is running under. */
|
|
819
499
|
groupId: string;
|
|
820
500
|
/** Stop this consumer. Equivalent to calling `client.stopConsumer(groupId)`. */
|
|
@@ -847,7 +527,7 @@ interface ConsumerHandle {
|
|
|
847
527
|
* });
|
|
848
528
|
* ```
|
|
849
529
|
*/
|
|
850
|
-
interface TransactionContext<T extends TopicMapConstraint<T>> {
|
|
530
|
+
export interface TransactionContext<T extends TopicMapConstraint<T>> {
|
|
851
531
|
send<K extends keyof T>(topic: K, message: T[K], options?: SendOptions): Promise<void>;
|
|
852
532
|
send<D extends TopicDescriptor<string & keyof T, T[string & keyof T]>>(descriptor: D, message: D["__type"], options?: SendOptions): Promise<void>;
|
|
853
533
|
sendBatch<K extends keyof T>(topic: K, messages: Array<BatchMessageItem<T[K]>>, options?: BatchSendOptions): Promise<void>;
|
|
@@ -869,7 +549,7 @@ interface TransactionContext<T extends TopicMapConstraint<T>> {
|
|
|
869
549
|
* });
|
|
870
550
|
* ```
|
|
871
551
|
*/
|
|
872
|
-
interface TransactionalHandlerContext<T extends TopicMapConstraint<T>> {
|
|
552
|
+
export interface TransactionalHandlerContext<T extends TopicMapConstraint<T>> {
|
|
873
553
|
/**
|
|
874
554
|
* Send a message as part of this message's transaction.
|
|
875
555
|
* The send is staged — it only becomes visible to consumers after the transaction commits.
|
|
@@ -899,7 +579,7 @@ interface TransactionalHandlerContext<T extends TopicMapConstraint<T>> {
|
|
|
899
579
|
* });
|
|
900
580
|
* ```
|
|
901
581
|
*/
|
|
902
|
-
interface RoutingOptions<E> {
|
|
582
|
+
export interface RoutingOptions<E> {
|
|
903
583
|
/** Header whose value determines which handler is invoked. */
|
|
904
584
|
header: string;
|
|
905
585
|
/**
|
|
@@ -925,7 +605,7 @@ interface RoutingOptions<E> {
|
|
|
925
605
|
* }, { maxMessages: 100, maxMs: 5_000 });
|
|
926
606
|
* ```
|
|
927
607
|
*/
|
|
928
|
-
interface WindowMeta {
|
|
608
|
+
export interface WindowMeta {
|
|
929
609
|
/** What triggered this flush: accumulated `maxMessages` messages, or the `maxMs` timer. */
|
|
930
610
|
trigger: "size" | "time";
|
|
931
611
|
/** Unix timestamp (ms) of the first message that entered the current window. */
|
|
@@ -940,7 +620,7 @@ interface WindowMeta {
|
|
|
940
620
|
* `retryTopics`, `retryTopicAssignmentTimeoutMs`, and `queueHighWaterMark`
|
|
941
621
|
* are excluded: they are incompatible with windowed accumulation.
|
|
942
622
|
*/
|
|
943
|
-
interface WindowConsumerOptions<T extends TopicMapConstraint<T> = TTopicMessageMap> extends Omit<ConsumerOptions<T>, "retryTopics" | "retryTopicAssignmentTimeoutMs" | "queueHighWaterMark"> {
|
|
623
|
+
export interface WindowConsumerOptions<T extends TopicMapConstraint<T> = TTopicMessageMap> extends Omit<ConsumerOptions<T>, "retryTopics" | "retryTopicAssignmentTimeoutMs" | "queueHighWaterMark"> {
|
|
944
624
|
/**
|
|
945
625
|
* Maximum number of messages to accumulate before flushing.
|
|
946
626
|
* When the buffer reaches this size the handler is called immediately,
|
|
@@ -954,5 +634,4 @@ interface WindowConsumerOptions<T extends TopicMapConstraint<T> = TTopicMessageM
|
|
|
954
634
|
*/
|
|
955
635
|
maxMs: number;
|
|
956
636
|
}
|
|
957
|
-
|
|
958
|
-
export { type TransactionalHandlerContext as A, type BatchMessageItem as B, type ClientId as C, type DeduplicationOptions as D, type EnvelopeHeaderOptions as E, type TtlExpiredContext as F, type GroupId as G, HEADER_CORRELATION_ID as H, type InferSchema as I, type WindowMeta as J, type KafkaInstrumentation as K, buildEnvelopeHeaders as L, type MessageHeaders as M, decodeHeaders as N, extractEnvelope as O, getEnvelopeContext as P, runWithEnvelopeContext as Q, type RetryOptions as R, type SchemaLike as S, type TopicMapConstraint as T, topic as U, type WindowConsumerOptions as W, type ConsumerOptions as a, type TopicDescriptor as b, type BatchMeta as c, type BatchSendOptions as d, type BeforeConsumeResult as e, type CircuitBreakerOptions as f, type CompressionType as g, type ConsumerHandle as h, type ConsumerInterceptor as i, type DlqReason as j, type EventEnvelope as k, HEADER_EVENT_ID as l, HEADER_LAMPORT_CLOCK as m, HEADER_SCHEMA_VERSION as n, HEADER_TIMESTAMP as o, HEADER_TRACEPARENT as p, type KafkaLogger as q, type KafkaMetrics as r, type MessageLostContext as s, type RoutingOptions as t, type SchemaParseContext as u, type SendOptions as v, type SubscribeRetryOptions as w, type TTopicMessageMap as x, type TopicsFrom as y, type TransactionContext as z };
|
|
637
|
+
//# sourceMappingURL=consumer.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consumer.types.d.ts","sourceRoot":"","sources":["../../../src/client/types/consumer.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pluggable backing store for Lamport-clock deduplication.
|
|
3
|
+
*
|
|
4
|
+
* By default deduplication state is held in memory (`InMemoryDedupStore`) and is
|
|
5
|
+
* reset on process restart or rebalance. Provide a custom `DedupStore` — backed
|
|
6
|
+
* by Redis, a database, or any external system — to make deduplication survive
|
|
7
|
+
* restarts and rebalances.
|
|
8
|
+
*
|
|
9
|
+
* The store is keyed by consumer `groupId` and `"topic:partition"`. Both methods
|
|
10
|
+
* may run synchronously or return a promise; `applyDeduplication` always awaits
|
|
11
|
+
* the result.
|
|
12
|
+
*
|
|
13
|
+
* **Failure semantics (fail-open):** if `getLastClock` or `setLastClock` throws
|
|
14
|
+
* or rejects, the error is logged and the message is treated as **not** a
|
|
15
|
+
* duplicate. This biases towards at-least-once delivery — a transient store
|
|
16
|
+
* outage never silently drops messages, it only weakens deduplication until the
|
|
17
|
+
* store recovers.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* // Minimal Redis-backed store (generic redis client pseudocode).
|
|
22
|
+
* class RedisDedupStore implements DedupStore {
|
|
23
|
+
* constructor(private readonly redis: RedisClient) {}
|
|
24
|
+
*
|
|
25
|
+
* private key(groupId: string, topicPartition: string): string {
|
|
26
|
+
* return `dedup:${groupId}:${topicPartition}`;
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* async getLastClock(groupId: string, topicPartition: string): Promise<number | undefined> {
|
|
30
|
+
* const raw = await this.redis.get(this.key(groupId, topicPartition));
|
|
31
|
+
* return raw === null ? undefined : Number(raw);
|
|
32
|
+
* }
|
|
33
|
+
*
|
|
34
|
+
* async setLastClock(groupId: string, topicPartition: string, clock: number): Promise<void> {
|
|
35
|
+
* await this.redis.set(this.key(groupId, topicPartition), String(clock));
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* await kafka.startConsumer(['payments'], handler, {
|
|
40
|
+
* deduplication: { strategy: 'drop', store: new RedisDedupStore(redis) },
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export interface DedupStore {
|
|
45
|
+
/** Return the last processed Lamport clock for a group+topic:partition, or undefined if none. */
|
|
46
|
+
getLastClock(groupId: string, topicPartition: string): number | undefined | Promise<number | undefined>;
|
|
47
|
+
/** Persist the last processed Lamport clock for a group+topic:partition. */
|
|
48
|
+
setLastClock(groupId: string, topicPartition: string, clock: number): void | Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=dedup.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedup.types.d.ts","sourceRoot":"","sources":["../../../src/client/types/dedup.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,WAAW,UAAU;IACzB,iGAAiG;IACjG,YAAY,CACV,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,GACrB,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACpD,4EAA4E;IAC5E,YAAY,CACV,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,GACZ,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB"}
|