@venizia/ignis-docs 0.2.0 → 0.2.1-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +14 -14
  2. package/content/best-practices/api-usage-examples.md +39 -19
  3. package/content/best-practices/architectural-patterns.md +22 -11
  4. package/content/best-practices/architecture-decisions.md +29 -16
  5. package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
  6. package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
  7. package/content/best-practices/code-style-standards/control-flow.md +33 -1
  8. package/content/best-practices/code-style-standards/documentation.md +28 -8
  9. package/content/best-practices/code-style-standards/function-patterns.md +15 -4
  10. package/content/best-practices/code-style-standards/index.md +7 -2
  11. package/content/best-practices/code-style-standards/naming-conventions.md +26 -2
  12. package/content/best-practices/code-style-standards/route-definitions.md +9 -5
  13. package/content/best-practices/code-style-standards/tooling.md +14 -1
  14. package/content/best-practices/code-style-standards/type-safety.md +39 -6
  15. package/content/best-practices/common-pitfalls.md +59 -35
  16. package/content/best-practices/contribution-workflow.md +6 -2
  17. package/content/best-practices/data-modeling.md +78 -62
  18. package/content/best-practices/deployment-strategies.md +56 -19
  19. package/content/best-practices/error-handling.md +182 -93
  20. package/content/best-practices/index.md +6 -0
  21. package/content/best-practices/performance-optimization.md +26 -13
  22. package/content/best-practices/security-guidelines.md +35 -9
  23. package/content/best-practices/testing-strategies.md +7 -2
  24. package/content/best-practices/troubleshooting-tips.md +27 -17
  25. package/content/extensions/components/api-reference.md +107 -322
  26. package/content/extensions/components/authentication/api.md +454 -603
  27. package/content/extensions/components/authentication/errors.md +121 -498
  28. package/content/extensions/components/authentication/index.md +88 -801
  29. package/content/extensions/components/authentication/usage.md +207 -956
  30. package/content/extensions/components/authorization/api.md +736 -656
  31. package/content/extensions/components/authorization/errors.md +168 -206
  32. package/content/extensions/components/authorization/index.md +82 -797
  33. package/content/extensions/components/authorization/usage.md +194 -527
  34. package/content/extensions/components/health-check.md +71 -243
  35. package/content/extensions/components/mail/api.md +504 -287
  36. package/content/extensions/components/mail/errors.md +73 -61
  37. package/content/extensions/components/mail/index.md +96 -467
  38. package/content/extensions/components/mail/usage.md +130 -172
  39. package/content/extensions/components/request-tracker.md +66 -173
  40. package/content/extensions/components/socket-io/api.md +195 -13
  41. package/content/extensions/components/socket-io/errors.md +3 -3
  42. package/content/extensions/components/socket-io/index.md +50 -337
  43. package/content/extensions/components/socket-io/usage.md +143 -26
  44. package/content/extensions/components/static-asset/api.md +410 -142
  45. package/content/extensions/components/static-asset/errors.md +110 -53
  46. package/content/extensions/components/static-asset/index.md +79 -608
  47. package/content/extensions/components/static-asset/usage.md +180 -300
  48. package/content/extensions/components/websocket/api.md +275 -399
  49. package/content/extensions/components/websocket/errors.md +47 -56
  50. package/content/extensions/components/websocket/index.md +74 -407
  51. package/content/extensions/components/websocket/usage.md +110 -341
  52. package/content/extensions/helpers/cron/index.md +51 -160
  53. package/content/extensions/helpers/crypto/index.md +62 -483
  54. package/content/extensions/helpers/crypto/reference.md +456 -0
  55. package/content/extensions/helpers/env/index.md +60 -178
  56. package/content/extensions/helpers/error/index.md +221 -207
  57. package/content/extensions/helpers/inversion/index.md +65 -556
  58. package/content/extensions/helpers/inversion/reference.md +522 -0
  59. package/content/extensions/helpers/kafka/admin.md +20 -1
  60. package/content/extensions/helpers/kafka/compile-binary.md +41 -35
  61. package/content/extensions/helpers/kafka/consumer.md +54 -20
  62. package/content/extensions/helpers/kafka/examples.md +21 -16
  63. package/content/extensions/helpers/kafka/index.md +80 -610
  64. package/content/extensions/helpers/kafka/producer.md +134 -5
  65. package/content/extensions/helpers/kafka/schema-registry.md +45 -70
  66. package/content/extensions/helpers/logger/hf-logger.md +193 -0
  67. package/content/extensions/helpers/logger/index.md +64 -563
  68. package/content/extensions/helpers/logger/pino.md +85 -0
  69. package/content/extensions/helpers/logger/reference.md +746 -0
  70. package/content/extensions/helpers/network/api.md +241 -195
  71. package/content/extensions/helpers/network/index.md +72 -530
  72. package/content/extensions/helpers/queue/index.md +72 -900
  73. package/content/extensions/helpers/queue/reference.md +467 -0
  74. package/content/extensions/helpers/redis/index.md +73 -645
  75. package/content/extensions/helpers/redis/reference.md +727 -0
  76. package/content/extensions/helpers/secrets/index.md +66 -0
  77. package/content/extensions/helpers/socket-io/api.md +305 -203
  78. package/content/extensions/helpers/socket-io/index.md +66 -432
  79. package/content/extensions/helpers/storage/api.md +564 -462
  80. package/content/extensions/helpers/storage/index.md +77 -573
  81. package/content/extensions/helpers/types/index.md +66 -499
  82. package/content/extensions/helpers/types/reference.md +650 -0
  83. package/content/extensions/helpers/uid/index.md +58 -227
  84. package/content/extensions/helpers/websocket/api.md +329 -216
  85. package/content/extensions/helpers/websocket/index.md +65 -503
  86. package/content/extensions/helpers/worker-thread/index.md +58 -396
  87. package/content/extensions/helpers/worker-thread/reference.md +428 -0
  88. package/content/guides/core-concepts/persistent/models.md +1 -1
  89. package/content/guides/core-concepts/persistent/search-typesense.md +3 -3
  90. package/content/guides/core-concepts/persistent/transactions.md +1 -1
  91. package/content/guides/core-concepts/secrets-vault.md +177 -0
  92. package/content/guides/core-concepts/services.md +1 -1
  93. package/content/guides/migrations/redis-helpers-migration.md +1 -1
  94. package/content/guides/migrations/unified-connectors-migration.md +2 -2
  95. package/content/guides/tutorials/ecommerce-api.md +3 -8
  96. package/content/references/base/application.md +1 -1
  97. package/content/references/base/connectors.md +79 -136
  98. package/content/references/base/datasources-reference.md +599 -0
  99. package/content/references/base/datasources.md +84 -444
  100. package/content/references/base/dependency-injection.md +17 -39
  101. package/content/references/base/filter-system/application-usage.md +69 -121
  102. package/content/references/base/filter-system/array-operators.md +12 -0
  103. package/content/references/base/filter-system/comparison-operators.md +12 -0
  104. package/content/references/base/filter-system/default-filter.md +136 -348
  105. package/content/references/base/filter-system/fields-order-pagination.md +38 -16
  106. package/content/references/base/filter-system/index.md +106 -257
  107. package/content/references/base/filter-system/json-filtering.md +12 -2
  108. package/content/references/base/filter-system/list-operators.md +16 -2
  109. package/content/references/base/filter-system/logical-operators.md +13 -0
  110. package/content/references/base/filter-system/null-operators.md +13 -0
  111. package/content/references/base/filter-system/pattern-matching.md +12 -0
  112. package/content/references/base/filter-system/quick-reference.md +11 -2
  113. package/content/references/base/filter-system/range-operators.md +12 -0
  114. package/content/references/base/filter-system/tips.md +70 -133
  115. package/content/references/base/filter-system/use-cases.md +156 -233
  116. package/content/references/base/middlewares.md +35 -21
  117. package/content/references/base/models-reference.md +886 -0
  118. package/content/references/base/models.md +80 -1452
  119. package/content/references/base/repositories/advanced.md +156 -192
  120. package/content/references/base/repositories/index.md +77 -650
  121. package/content/references/base/repositories/mixins.md +22 -18
  122. package/content/references/base/repositories/relations.md +123 -171
  123. package/content/references/base/repositories/soft-deletable.md +58 -56
  124. package/content/references/base/secrets.md +263 -0
  125. package/content/references/base/services.md +2 -2
  126. package/content/references/configuration/environment-variables.md +48 -4
  127. package/content/references/configuration/index.md +49 -31
  128. package/content/references/quick-reference.md +3 -16
  129. package/content/references/utilities/crypto.md +35 -76
  130. package/content/references/utilities/date.md +33 -73
  131. package/content/references/utilities/index.md +1 -1
  132. package/content/references/utilities/jsx-reference.md +298 -0
  133. package/content/references/utilities/jsx.md +82 -525
  134. package/content/references/utilities/module.md +29 -62
  135. package/content/references/utilities/parse.md +34 -64
  136. package/content/references/utilities/performance.md +33 -58
  137. package/content/references/utilities/promise.md +28 -62
  138. package/content/references/utilities/request.md +57 -218
  139. package/content/references/utilities/schema.md +43 -137
  140. package/content/references/utilities/statuses-reference.md +361 -0
  141. package/content/references/utilities/statuses.md +63 -667
  142. package/package.json +8 -8
@@ -1,646 +1,116 @@
1
- # Kafka
2
-
3
- Apache Kafka event streaming with producer, consumer, admin, and schema registry helpers. Built on [`@platformatic/kafka`](https://github.com/platformatic/kafka) v1.30.0 -- a pure TypeScript Kafka client with zero native dependencies.
4
-
5
- ## Overview
6
-
7
- The Kafka module provides four helper classes built on a shared `BaseKafkaHelper` base:
8
-
9
- | Class | Wraps | Use Case |
10
- |-------|-------|----------|
11
- | `KafkaProducerHelper` | `Producer` | Publish messages, transactions |
12
- | `KafkaConsumerHelper` | `Consumer` | Consume messages with consumer groups, lag monitoring |
13
- | `KafkaAdminHelper` | `Admin` | Manage topics, partitions, groups, ACLs, configs |
14
- | `KafkaSchemaRegistryHelper` | `ConfluentSchemaRegistry` | Schema validation and auto ser/deser |
15
-
16
- All helpers (except schema registry) extend `BaseKafkaHelper` which provides:
17
-
18
- - **Scoped logging** via `BaseHelper` (Winston with daily rotation)
19
- - **Health tracking** -- per-broker connection tracking via `isHealthy()`, `isReady()`, `getHealthStatus()`, `getConnectedBrokerCount()`
20
- - **Broker event callbacks** -- `onBrokerConnect`, `onBrokerDisconnect`
21
- - **Broker failure tracking** -- automatic `configureBrokerFailed()` sets status to `'disconnected'` only when all brokers are gone
22
- - **Graceful shutdown** -- timeout-based with force fallback
23
- - **Sensible defaults** via `KafkaDefaults` constants
24
- - **Factory pattern** via `newInstance()` static method
25
-
26
- Use `getProducer()`, `getConsumer()`, or `getAdmin()` to access the full underlying `@platformatic/kafka` API directly.
27
-
28
- ### Import Path
29
-
30
- ```typescript
31
- // Helpers & constants (via subpath export)
32
- import {
33
- KafkaProducerHelper,
34
- KafkaConsumerHelper,
35
- KafkaAdminHelper,
36
- KafkaSchemaRegistryHelper,
37
- BaseKafkaHelper,
38
- KafkaDefaults,
39
- KafkaAcks,
40
- KafkaGroupProtocol,
41
- KafkaHealthStatuses,
42
- KafkaClientEvents,
43
- } from '@venizia/ignis-helpers/kafka';
44
-
45
- // Types
46
- import type {
47
- IKafkaConnectionOptions,
48
- IKafkaProducerOptions,
49
- IKafkaConsumerOptions,
50
- IKafkaAdminOptions,
51
- IKafkaConsumeStartOptions,
52
- IKafkaSchemaRegistryOptions,
53
- IKafkaTransactionContext,
54
- IKafkaBaseOptions,
55
- TKafkaAcks,
56
- TKafkaGroupProtocol,
57
- TKafkaHealthStatus,
58
- TKafkaBrokerEventCallback,
59
- TKafkaMessageCallback,
60
- TKafkaMessageDoneCallback,
61
- TKafkaMessageErrorCallback,
62
- TKafkaGroupJoinCallback,
63
- TKafkaGroupLeaveCallback,
64
- TKafkaGroupRebalanceCallback,
65
- TKafkaHeartbeatErrorCallback,
66
- TKafkaLagCallback,
67
- TKafkaLagErrorCallback,
68
- TKafkaTransactionCallback,
69
- } from '@venizia/ignis-helpers/kafka';
70
-
71
- // @platformatic/kafka (direct usage)
72
- import {
73
- Producer, Consumer, Admin, MessagesStream,
74
- stringSerializers, stringDeserializers,
75
- stringSerializer, stringDeserializer,
76
- jsonSerializer, jsonDeserializer,
77
- serializersFrom, deserializersFrom,
78
- } from '@platformatic/kafka';
79
-
80
- import type {
81
- Message, MessageToProduce,
82
- SendOptions, ConsumeOptions,
83
- Serializers, Deserializers,
84
- SASLOptions, ConnectionOptions,
85
- } from '@platformatic/kafka';
86
- ```
87
-
88
- > [!NOTE]
89
- > Kafka helpers are **not** re-exported from the main `@venizia/ignis-helpers` entry point. You must use the `@venizia/ignis-helpers/kafka` subpath import. This keeps the optional `@platformatic/kafka` peer dependency isolated for tree-shaking.
90
-
91
- > [!WARNING]
92
- > Compiling an application that uses these helpers with `bun build --compile` produces a binary that dies on startup with `ENOENT: /$bunfs/dist/native.wasm`. The build must register `platformaticWasmPlugin` from `@venizia/ignis-helpers/kafka` -- see [Compiling to a Single Binary](./compile-binary.md).
93
-
94
- ### Installation
95
-
96
- ```bash
97
- bun add @platformatic/kafka
98
- ```
99
-
100
- ## Architecture
101
-
102
- ### Class Hierarchy
103
-
104
- ```
105
- BaseHelper (scoped logging, identifier)
106
- +-- BaseKafkaHelper<TClient> (health tracking, broker events, graceful shutdown)
107
- | +-- KafkaProducerHelper<K,V,HK,HV>
108
- | +-- KafkaConsumerHelper<K,V,HK,HV>
109
- | +-- KafkaAdminHelper
110
- |
111
- +-- KafkaSchemaRegistryHelper<K,V,HK,HV> (no broker connection)
112
- ```
113
-
114
- ### BaseKafkaHelper
115
-
116
- All Kafka helpers (except schema registry) extend `BaseKafkaHelper<TClient>`, which provides:
117
-
118
- ```typescript
119
- abstract class BaseKafkaHelper<TClient extends Base<BaseOptions>> extends BaseHelper {
120
- // Health
121
- isHealthy(): boolean; // true when at least one broker is connected
122
- isReady(): boolean; // healthStatus === 'connected' (consumer overrides: + isActive())
123
- getHealthStatus(): TKafkaHealthStatus; // 'connected' | 'disconnected' | 'unknown'
124
- getConnectedBrokerCount(): number; // number of currently connected brokers
125
-
126
- // Shutdown (used by subclasses)
127
- protected closeClient(): Promise<void>;
128
- protected gracefulCloseClient(): Promise<void>; // races closeClient vs shutdownTimeout
129
- protected resetHealthState(): void; // clears broker tracking + sets 'disconnected'
130
- }
131
- ```
132
-
133
- Health tracking uses a **per-broker connection set** (`host:port` keys). A single idle broker disconnect does not make the client unhealthy -- only when **all** brokers are disconnected does `isHealthy()` return `false`.
134
-
135
- Health status transitions automatically via broker events:
136
- - `client:broker:connect` -> adds broker, sets `healthStatus` to `'connected'`
137
- - `client:broker:disconnect` -> removes broker, sets `healthStatus` to `'disconnected'` only when all brokers are gone
138
- - `client:broker:failed` -> removes broker, sets `healthStatus` to `'disconnected'` only when all brokers are gone
139
- - `close()` -> clears all brokers, sets `healthStatus` to `'disconnected'`
140
-
141
- ## Connection Options
142
-
143
- All three helpers share a common base interface `IKafkaConnectionOptions` which extends `@platformatic/kafka`'s `ConnectionOptions`.
144
-
145
- ```typescript
146
- interface IKafkaConnectionOptions extends ConnectionOptions {
147
- bootstrapBrokers: string[];
148
- clientId: string;
149
- retries?: number; // Default: 3
150
- retryDelay?: number; // Default: 1000ms
151
- }
152
- ```
153
-
154
- ### Full Options Table
155
-
156
- | Option | Type | Default | Description |
157
- |--------|------|---------|-------------|
158
- | `bootstrapBrokers` | `string[]` | -- | Kafka broker addresses (`host:port`). **Required** |
159
- | `clientId` | `string` | -- | Unique client identifier. **Required** |
160
- | `retries` | `number` | `3` | Number of connection retries before failing |
161
- | `retryDelay` | `number` | `1000` | Delay between retries in milliseconds |
162
- | `sasl` | `SASLOptions` | -- | SASL authentication configuration |
163
- | `tls` | `TLSConnectionOptions` | -- | TLS/SSL connection options |
164
- | `ssl` | `TLSConnectionOptions` | -- | Alias for `tls` |
165
- | `connectTimeout` | `number` | -- | TCP connection timeout in milliseconds |
166
- | `requestTimeout` | `number` | -- | Kafka request timeout in milliseconds |
167
-
168
- ### Shared Helper Options
169
-
170
- These options are available on all three helpers (`IKafkaProducerOptions`, `IKafkaConsumerOptions`, `IKafkaAdminOptions`):
171
-
172
- | Option | Type | Default | Description |
173
- |--------|------|---------|-------------|
174
- | `identifier` | `string` | `'kafka-{type}'` | Scoped logging identifier |
175
- | `shutdownTimeout` | `number` | `30000` | Graceful shutdown timeout in ms |
176
- | `onBrokerConnect` | `TKafkaBrokerEventCallback` | -- | Called when broker connects |
177
- | `onBrokerDisconnect` | `TKafkaBrokerEventCallback` | -- | Called when broker disconnects |
178
-
179
- ### SASL Authentication
180
-
181
- `@platformatic/kafka` supports five SASL mechanisms:
1
+ ---
2
+ title: Kafka
3
+ description: Apache Kafka producer, consumer, admin, and schema registry helpers built on a pure TypeScript client
4
+ difficulty: intermediate
5
+ ---
182
6
 
183
- | Mechanism | Use Case |
184
- |-----------|----------|
185
- | `PLAIN` | Simple username/password (use with TLS in production) |
186
- | `SCRAM-SHA-256` | Challenge-response, password never sent in plaintext |
187
- | `SCRAM-SHA-512` | Same as SHA-256 with stronger hash |
188
- | `OAUTHBEARER` | Token-based (Azure Event Hubs, Confluent Cloud) |
189
- | `GSSAPI` | Kerberos authentication |
190
-
191
- ```typescript
192
- interface SASLOptions {
193
- mechanism: 'PLAIN' | 'SCRAM-SHA-256' | 'SCRAM-SHA-512' | 'OAUTHBEARER' | 'GSSAPI';
194
- username?: string | CredentialProvider;
195
- password?: string | CredentialProvider;
196
- token?: string | CredentialProvider;
197
- oauthBearerExtensions?: Record<string, string> | CredentialProvider<Record<string, string>>;
198
- authenticate?: SASLCustomAuthenticator;
199
- }
200
- ```
201
-
202
- #### SCRAM-SHA-512 Example
203
-
204
- ```typescript
205
- const helper = KafkaConsumerHelper.newInstance({
206
- bootstrapBrokers: ['broker1:9092', 'broker2:9092', 'broker3:9092'],
207
- clientId: 'my-consumer',
208
- groupId: 'my-group',
209
- sasl: {
210
- mechanism: 'SCRAM-SHA-512',
211
- username: 'kafka-user',
212
- password: 'kafka-password',
213
- },
214
- connectTimeout: 30_000,
215
- requestTimeout: 30_000,
216
- onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}:${broker.port}`),
217
- });
218
- ```
219
-
220
- #### OAUTHBEARER Example
221
-
222
- ```typescript
223
- const helper = KafkaProducerHelper.newInstance({
224
- bootstrapBrokers: ['pkc-xxxxx.us-west-2.aws.confluent.cloud:9092'],
225
- clientId: 'my-producer',
226
- sasl: {
227
- mechanism: 'OAUTHBEARER',
228
- token: async () => {
229
- const response = await fetch('https://auth.example.com/token', { method: 'POST' });
230
- const { access_token } = await response.json();
231
- return access_token;
232
- },
233
- },
234
- tls: true,
235
- });
236
- ```
237
-
238
- #### TLS Without SASL
239
-
240
- ```typescript
241
- const helper = KafkaProducerHelper.newInstance({
242
- bootstrapBrokers: ['broker:9093'],
243
- clientId: 'my-producer',
244
- tls: {
245
- ca: fs.readFileSync('/path/to/ca.pem'),
246
- cert: fs.readFileSync('/path/to/client-cert.pem'),
247
- key: fs.readFileSync('/path/to/client-key.pem'),
248
- },
249
- });
250
- ```
251
-
252
- ## Serialization & Deserialization
253
-
254
- `@platformatic/kafka`'s default wire format is `Buffer`. The helpers default generic types to `string` (matching common usage), but you must provide serializers/deserializers explicitly.
255
-
256
- ### Built-in Serializers
257
-
258
- | Export | Type | Description |
259
- |--------|------|-------------|
260
- | `stringSerializer` | `Serializer<string>` | `string -> Buffer` (UTF-8) |
261
- | `stringDeserializer` | `Deserializer<string>` | `Buffer -> string` (UTF-8) |
262
- | `jsonSerializer` | `Serializer<T>` | `object -> Buffer` (JSON.stringify + UTF-8) |
263
- | `jsonDeserializer` | `Deserializer<T>` | `Buffer -> object` (UTF-8 + JSON.parse) |
264
- | `stringSerializers` | `Serializers<string, string, string, string>` | All four positions as string |
265
- | `stringDeserializers` | `Deserializers<string, string, string, string>` | All four positions as string |
7
+ # Kafka
266
8
 
267
- ### Helper Functions
9
+ The Kafka helpers wrap `@platformatic/kafka` with four scoped classes - producer, consumer, admin, and schema registry - that add health tracking, graceful shutdown, and IGNIS-style scoped logging on top of the underlying client.
268
10
 
269
- | Export | Signature | Description |
270
- |--------|-----------|-------------|
271
- | `serializersFrom(s)` | `<T>(s: Serializer<T>) => Serializers<T, T, T, T>` | Create full serializers from a single serializer |
272
- | `deserializersFrom(d)` | `<T>(d: Deserializer<T>) => Deserializers<T, T, T, T>` | Create full deserializers from a single deserializer |
11
+ ## In one example
273
12
 
274
- ### String Serialization
13
+ The smallest real use: create a producer, send a message through the underlying client, and close it.
275
14
 
276
15
  ```typescript
277
- import { stringSerializers, stringDeserializers } from '@platformatic/kafka';
16
+ import { KafkaProducerHelper } from '@venizia/ignis-helpers/kafka';
17
+ import { stringSerializers } from '@platformatic/kafka';
278
18
 
279
19
  const producer = KafkaProducerHelper.newInstance({
280
20
  bootstrapBrokers: ['localhost:9092'],
281
- clientId: 'my-producer',
21
+ clientId: 'order-producer',
282
22
  serializers: stringSerializers,
283
23
  });
284
24
 
285
- const consumer = KafkaConsumerHelper.newInstance({
286
- bootstrapBrokers: ['localhost:9092'],
287
- clientId: 'my-consumer',
288
- groupId: 'my-group',
289
- deserializers: stringDeserializers,
290
- onMessage: async ({ message }) => {
291
- console.log(message.key, message.value); // both strings
292
- },
293
- });
294
- ```
295
-
296
- ### JSON Serialization
297
-
298
- ```typescript
299
- import {
300
- jsonSerializer, jsonDeserializer,
301
- stringSerializer, stringDeserializer,
302
- serializersFrom, deserializersFrom,
303
- } from '@platformatic/kafka';
304
-
305
- const producer = KafkaProducerHelper.newInstance({
306
- bootstrapBrokers: ['localhost:9092'],
307
- clientId: 'my-producer',
308
- serializers: { ...serializersFrom(jsonSerializer), key: stringSerializer },
309
- });
310
-
311
25
  await producer.getProducer().send({
312
- messages: [{
313
- topic: 'orders',
314
- key: 'order-123',
315
- value: { id: '123', status: 'created', amount: 99 },
316
- }],
317
- });
318
-
319
- const consumer = KafkaConsumerHelper.newInstance({
320
- bootstrapBrokers: ['localhost:9092'],
321
- clientId: 'my-consumer',
322
- groupId: 'my-group',
323
- deserializers: { ...deserializersFrom(jsonDeserializer), key: stringDeserializer },
324
- onMessage: async ({ message }) => {
325
- console.log(message.value.id, message.value.status); // typed object
326
- },
327
- });
328
- ```
329
-
330
- ### Schema Registry Serialization
331
-
332
- For schema-validated serialization (Avro, Protobuf, JSON Schema), use the schema registry helper:
333
-
334
- ```typescript
335
- const registry = KafkaSchemaRegistryHelper.newInstance({
336
- url: 'http://localhost:8081',
337
- });
338
-
339
- const producer = KafkaProducerHelper.newInstance({
340
- bootstrapBrokers: ['localhost:9092'],
341
- clientId: 'my-producer',
342
- registry: registry.getRegistry(),
26
+ messages: [{ topic: 'orders', key: 'order-1', value: JSON.stringify({ status: 'created' }) }],
343
27
  });
344
28
 
345
- const consumer = KafkaConsumerHelper.newInstance({
346
- bootstrapBrokers: ['localhost:9092'],
347
- clientId: 'my-consumer',
348
- groupId: 'my-group',
349
- registry: registry.getRegistry(),
350
- onMessage: async ({ message }) => {
351
- // message.value is auto-deserialized using registered schema
352
- },
353
- });
29
+ await producer.close();
354
30
  ```
355
31
 
356
- See **[Schema Registry](./schema-registry)** for full documentation.
357
-
358
- ## Generic Type Parameters
32
+ `getProducer()` returns the full `@platformatic/kafka` `Producer`. Every helper follows this same pattern: construct through `newInstance()`, reach the native client through `getProducer()` / `getConsumer()` / `getAdmin()`, close through the helper.
359
33
 
360
- All helpers (and their option interfaces) support generic type parameters controlling the serialization types:
34
+ ## How it works
361
35
 
362
- ```typescript
363
- class KafkaProducerHelper<
364
- KeyType = string,
365
- ValueType = string,
366
- HeaderKeyType = string,
367
- HeaderValueType = string,
368
- >
369
- ```
370
-
371
- | Parameter | Default | Description |
372
- |-----------|---------|-------------|
373
- | `KeyType` | `string` | Message key type after serialization/deserialization |
374
- | `ValueType` | `string` | Message value type after serialization/deserialization |
375
- | `HeaderKeyType` | `string` | Header key type |
376
- | `HeaderValueType` | `string` | Header value type |
36
+ - **Four helpers, one job each.**
377
37
 
378
- > [!NOTE]
379
- > `@platformatic/kafka` defaults to `Buffer` for all four positions. The helpers default to `string` which is more common for application code. If you don't pass serializers, your messages will be sent/received as `Buffer`.
38
+ | Class | Wraps | Use case |
39
+ |---|---|---|
40
+ | `KafkaProducerHelper` | `Producer` | Publish messages, run transactions |
41
+ | `KafkaConsumerHelper` | `Consumer` | Consume via consumer groups, monitor lag |
42
+ | `KafkaAdminHelper` | `Admin` | Manage topics, partitions, groups, ACLs, configs |
43
+ | `KafkaSchemaRegistryHelper` | `ConfluentSchemaRegistry` | Schema-validated serialization (Avro/Protobuf/JSON Schema) |
380
44
 
381
- ```typescript
382
- // Default: string types (most common)
383
- const helper = KafkaProducerHelper.newInstance({ ... });
45
+ - **The three connected helpers share an identical health & close API**, regardless of which client they wrap:
384
46
 
385
- // Custom: string keys, JSON object values
386
- const helper = KafkaProducerHelper.newInstance<string, MyEvent, string, string>({
387
- serializers: { ...serializersFrom(jsonSerializer), key: stringSerializer },
388
- ...
389
- });
390
- ```
47
+ ```typescript
48
+ const producer = KafkaProducerHelper.newInstance({ bootstrapBrokers, clientId });
49
+ const consumer = KafkaConsumerHelper.newInstance({ bootstrapBrokers, clientId, groupId });
50
+ const admin = KafkaAdminHelper.newInstance({ bootstrapBrokers, clientId });
391
51
 
392
- ## Constants
393
-
394
- ### KafkaDefaults
395
-
396
- Centralized default values used by all helpers.
397
-
398
- ```typescript
399
- import { KafkaDefaults } from '@venizia/ignis-helpers/kafka';
400
- ```
401
-
402
- | Constant | Value | Scope | Description |
403
- |----------|-------|-------|-------------|
404
- | `RETRIES` | `3` | Shared | Connection retry count |
405
- | `RETRY_DELAY` | `1000` | Shared | Retry delay in ms |
406
- | `SHUTDOWN_TIMEOUT` | `30000` | Shared | Graceful shutdown timeout in ms |
407
- | `STRICT` | `true` | Producer | Fail on unknown topics |
408
- | `AUTOCREATE_TOPICS` | `false` | Producer | Auto-create topics on produce |
409
- | `AUTOCOMMIT` | `false` | Consumer | Auto-commit offsets |
410
- | `SESSION_TIMEOUT` | `60000` | Consumer | Session timeout in ms |
411
- | `HEARTBEAT_INTERVAL` | `10000` | Consumer | Heartbeat interval in ms |
412
- | `HIGH_WATER_MARK` | `1024` | Consumer | Stream buffer size (messages) |
413
- | `MIN_BYTES` | `1` | Consumer | Min bytes per fetch |
414
- | `METADATA_MAX_AGE` | `300000` | Consumer | Metadata cache TTL in ms |
415
- | `GROUP_PROTOCOL` | `'classic'` | Consumer | Default group protocol |
416
- | `CONSUME_MODE` | `'committed'` | Consumer | Default consume mode |
417
- | `CONSUME_FALLBACK_MODE` | `'latest'` | Consumer | Default consume fallback mode |
418
- | `LAG_MONITOR_INTERVAL` | `30000` | Consumer | Lag monitoring poll interval in ms |
419
-
420
- ### KafkaHealthStatuses
421
-
422
- Health status values used by all Kafka helpers.
423
-
424
- ```typescript
425
- import { KafkaHealthStatuses } from '@venizia/ignis-helpers/kafka';
426
- ```
52
+ producer.isHealthy(); // true once at least one broker is connected
53
+ consumer.isReady(); // true once connected AND consumer.isActive()
54
+ admin.getHealthStatus(); // 'connected' | 'disconnected' | 'unknown'
427
55
 
428
- | Constant | Value | Description |
429
- |----------|-------|-------------|
430
- | `CONNECTED` | `'connected'` | Broker connection established |
431
- | `DISCONNECTED` | `'disconnected'` | Broker connection lost or closed |
432
- | `UNKNOWN` | `'unknown'` | Initial state before first broker event |
56
+ await Promise.all([producer.close(), consumer.close(), admin.close()]); // graceful, force fallback
57
+ ```
433
58
 
434
- ### KafkaClientEvents
435
-
436
- Event name constants for `@platformatic/kafka` event emitters.
437
-
438
- ```typescript
439
- import { KafkaClientEvents } from '@venizia/ignis-helpers/kafka';
440
- ```
441
-
442
- | Constant | Value | Scope |
443
- |----------|-------|-------|
444
- | `BROKER_CONNECT` | `'client:broker:connect'` | All clients |
445
- | `BROKER_DISCONNECT` | `'client:broker:disconnect'` | All clients |
446
- | `BROKER_FAILED` | `'client:broker:failed'` | All clients |
447
- | `CONSUMER_GROUP_JOIN` | `'consumer:group:join'` | Consumer |
448
- | `CONSUMER_GROUP_LEAVE` | `'consumer:group:leave'` | Consumer |
449
- | `CONSUMER_GROUP_REBALANCE` | `'consumer:group:rebalance'` | Consumer |
450
- | `CONSUMER_HEARTBEAT_ERROR` | `'consumer:heartbeat:error'` | Consumer |
451
- | `CONSUMER_LAG` | `'consumer:lag'` | Consumer |
452
- | `CONSUMER_LAG_ERROR` | `'consumer:lag:error'` | Consumer |
453
- | `STREAM_DATA` | `'data'` | Stream |
454
- | `STREAM_ERROR` | `'error'` | Stream |
455
-
456
- ### KafkaAcks
457
-
458
- Producer acknowledgment levels.
459
-
460
- ```typescript
461
- import { KafkaAcks } from '@venizia/ignis-helpers/kafka';
462
- ```
463
-
464
- | Constant | Value | Description | Trade-off |
465
- |----------|-------|-------------|-----------|
466
- | `NONE` | `0` | No acknowledgment -- fire-and-forget | Fastest, no durability guarantee |
467
- | `LEADER` | `1` | Leader broker acknowledges | Fast, leader-durable |
468
- | `ALL` | `-1` | All in-sync replicas acknowledge | Slowest, fully durable |
469
-
470
- ### KafkaGroupProtocol
471
-
472
- Consumer group protocol versions.
473
-
474
- ```typescript
475
- import { KafkaGroupProtocol } from '@venizia/ignis-helpers/kafka';
476
- ```
477
-
478
- | Constant | Value | Description |
479
- |----------|-------|-------------|
480
- | `CLASSIC` | `'classic'` | Classic consumer group protocol (default, all Kafka versions) |
481
- | `CONSUMER` | `'consumer'` | New consumer group protocol -- KIP-848 (Kafka 3.7+) |
482
-
483
- ### Derived Types
484
-
485
- ```typescript
486
- import type { TKafkaAcks, TKafkaGroupProtocol, TKafkaHealthStatus } from '@venizia/ignis-helpers/kafka';
487
-
488
- // TKafkaAcks = 0 | 1 | -1
489
- // TKafkaGroupProtocol = 'classic' | 'consumer'
490
- // TKafkaHealthStatus = 'connected' | 'disconnected' | 'unknown'
491
- ```
59
+ ```
60
+ BaseHelper (scoped logging, identifier)
61
+ +-- BaseKafkaHelper<TClient> (health tracking, broker events, graceful shutdown)
62
+ | +-- KafkaProducerHelper<K,V,HK,HV>
63
+ | +-- KafkaConsumerHelper<K,V,HK,HV>
64
+ | +-- KafkaAdminHelper
65
+ |
66
+ +-- KafkaSchemaRegistryHelper<K,V,HK,HV> (no broker connection)
67
+ ```
492
68
 
493
- ## Compression
69
+ - **`BaseKafkaHelper` is the shared base** for the three connected helpers (everything but the schema registry). It tracks per-broker connection state (`host:port` keys), so one idle disconnect never flips `isHealthy()` to `false` - only when every broker is gone. `isReady()`, `getHealthStatus()`, and `getConnectedBrokerCount()` read the same state, and `close({ isForce })` gives every connected helper the same two-phase graceful-then-force shutdown.
70
+ - **Health status follows broker events automatically.** `client:broker:connect` marks a broker connected; `client:broker:disconnect` and `client:broker:failed` remove it and only flip the status to `'disconnected'` once every broker is gone; `close()` clears everything. You never set `healthStatus` yourself.
71
+ - **`KafkaSchemaRegistryHelper` extends `BaseHelper` directly.** It opens no broker connection, so it has no health tracking - it's a configuration wrapper you hand to a producer or consumer via `registry`.
72
+ - **Everything lives at the `/kafka` sub-path, never the root barrel.** `@platformatic/kafka` is an optional peer dependency (`^2.1.0` - `bun add @platformatic/kafka`); keeping it off the root barrel lets apps that never touch Kafka tree-shake it away entirely.
73
+ - **Generics default to `string`.** All four classes accept `<KeyType, ValueType, HeaderKeyType, HeaderValueType>` generics. Without serializers/deserializers, messages travel as raw `Buffer`.
74
+ - **`newInstance()` is the documented entry point.** Every class also exposes a public constructor, but `newInstance()` is what every example on these pages uses, and it carries the same generic inference: `KafkaProducerHelper.newInstance<string, MyEvent>({ ... })`.
75
+ - **Compiling to a single binary needs one extra step.** `bun build --compile` crashes at startup with `ENOENT: native.wasm` unless the build registers `platformaticWasmPlugin()` - see [Compiling to a Single Binary](./compile-binary).
494
76
 
495
- `@platformatic/kafka` supports five compression algorithms:
77
+ **Exported constants** (`@venizia/ignis-helpers/kafka`):
496
78
 
497
- | Algorithm | Value | Description |
498
- |-----------|-------|-------------|
499
- | None | `'none'` | No compression (default) |
500
- | GZIP | `'gzip'` | Good compression ratio, moderate CPU |
501
- | Snappy | `'snappy'` | Fast compression, moderate ratio |
502
- | LZ4 | `'lz4'` | Very fast, good for high-throughput |
503
- | Zstandard | `'zstd'` | Best ratio, moderate CPU |
79
+ | Constant | Exports | Purpose |
80
+ |---|---|---|
81
+ | `KafkaDefaults` | Timeouts, retry counts, buffer sizes | Every default value the helpers fall back to |
82
+ | `KafkaAcks` | `NONE` (`0`) / `LEADER` (`1`) / `ALL` (`-1`) | Producer acknowledgment levels |
83
+ | `KafkaGroupProtocol` | `CLASSIC` / `CONSUMER` | Consumer group protocol version |
84
+ | `KafkaHealthStatuses` | `CONNECTED` / `DISCONNECTED` / `UNKNOWN` | `getHealthStatus()` return values |
85
+ | `KafkaClientEvents` | Raw platformatic event names | Direct listening on `getProducer()` / `getConsumer()` / `getAdmin()` |
504
86
 
505
- ```typescript
506
- const helper = KafkaProducerHelper.newInstance({
507
- bootstrapBrokers: ['localhost:9092'],
508
- clientId: 'my-producer',
509
- serializers: stringSerializers,
510
- compression: 'zstd',
511
- });
512
-
513
- // Override per-send
514
- await helper.getProducer().send({
515
- messages: [{ topic: 'logs', key: 'l1', value: largePayload }],
516
- compression: 'lz4',
517
- });
518
- ```
519
-
520
- ## Quick Usage Comparison
521
-
522
- ### Construction
523
-
524
- ```typescript
525
- // Admin
526
- const admin = KafkaAdminHelper.newInstance({
527
- bootstrapBrokers: ['127.0.0.1:29092'],
528
- clientId: 'my-admin',
529
- onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}`),
530
- onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
531
- });
532
-
533
- // Producer
534
- const producer = KafkaProducerHelper.newInstance({
535
- bootstrapBrokers: ['127.0.0.1:29092'],
536
- clientId: 'my-producer',
537
- acks: -1,
538
- idempotent: true,
539
- transactionalId: 'my-tx',
540
- onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}`),
541
- onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
542
- });
543
-
544
- // Consumer
545
- const consumer = KafkaConsumerHelper.newInstance({
546
- bootstrapBrokers: ['127.0.0.1:29092'],
547
- clientId: 'my-consumer',
548
- groupId: 'my-group',
549
- onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}`),
550
- onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
551
- onMessage: async ({ message }) => {
552
- console.log('Received:', message.value);
553
- await message.commit();
554
- },
555
- onMessageDone: ({ message }) => console.log('Done:', message.key),
556
- onMessageError: ({ error, message }) => console.error('Error:', error),
557
- onGroupJoin: ({ groupId, memberId }) => console.log(`Joined ${groupId}`),
558
- onGroupLeave: ({ groupId }) => console.log(`Left ${groupId}`),
559
- onGroupRebalance: ({ groupId }) => console.log(`Rebalance ${groupId}`),
560
- onHeartbeatError: ({ error }) => console.error('Heartbeat:', error),
561
- onLag: ({ lag }) => console.log('Lag:', lag),
562
- onLagError: ({ error }) => console.error('Lag error:', error),
563
- });
564
- ```
565
-
566
- ### Core Operations
567
-
568
- | Admin | Producer | Consumer |
569
- |-------|----------|----------|
570
- | `admin.getAdmin()` | `producer.getProducer()` | `consumer.getConsumer()` |
571
- | -- | `producer.getProducer().send(...)` | `await consumer.start({ topics: ['t1'] })` |
572
- | -- | `await producer.runInTransaction(async ({ send, addConsumer, addOffset }) => { ... })` | `consumer.startLagMonitoring({ topics: ['t1'], interval: 10_000 })` |
573
- | -- | -- | `consumer.stopLagMonitoring()` |
574
- | -- | -- | `consumer.getStream()` |
575
-
576
- ### Health Checks
577
-
578
- ```typescript
579
- // All three -- identical API
580
- helper.isHealthy(); // true when at least one broker connected
581
- helper.isReady(); // Admin/Producer: same as isHealthy()
582
- // Consumer: isHealthy() + consumer.isActive()
583
- helper.getHealthStatus(); // 'connected' | 'disconnected' | 'unknown'
584
- ```
585
-
586
- ### Shutdown
587
-
588
- ```typescript
589
- // All three -- identical API
590
- await helper.close(); // graceful (timeout -> force fallback)
591
- await helper.close({ isForce: true }); // immediate force close
592
- ```
593
-
594
- ### With Schema Registry
595
-
596
- ```typescript
597
- const registry = KafkaSchemaRegistryHelper.newInstance({ url: 'http://localhost:8081' });
598
-
599
- const producer = KafkaProducerHelper.newInstance({
600
- ...,
601
- registry: registry.getRegistry(),
602
- // or use registry.getSerializers() for manual serializer config
603
- });
604
-
605
- const consumer = KafkaConsumerHelper.newInstance({
606
- ...,
607
- registry: registry.getRegistry(),
608
- // or use registry.getDeserializers() for manual deserializer config
609
- });
610
- ```
611
-
612
- ### Transaction (Producer Only)
613
-
614
- ```typescript
615
- const result = await producer.runInTransaction(async ({ send, addConsumer, addOffset }) => {
616
- // Send messages within transaction
617
- const result = await send({
618
- messages: [{ topic: 'orders', key: 'o1', value: '{"status":"created"}' }],
619
- });
87
+ ## Pages
620
88
 
621
- // Optionally add consumer for exactly-once semantics
622
- await addConsumer(consumer.getConsumer());
623
- await addOffset(message);
89
+ Each class, and the one build-time gotcha, gets its own page:
624
90
 
625
- return result;
626
- });
627
- ```
91
+ | Page | Covers |
92
+ |---|---|
93
+ | [Producer](./producer) | `KafkaProducerHelper` - connection & SASL setup, serialization, compression, transactions, full `Producer` API |
94
+ | [Consumer](./consumer) | `KafkaConsumerHelper` - message callbacks, automatic reconnect, lag monitoring, full `Consumer` API |
95
+ | [Admin](./admin) | `KafkaAdminHelper` - topic, group, offset, ACL, and quota management |
96
+ | [Schema Registry](./schema-registry) | `KafkaSchemaRegistryHelper` for Avro/Protobuf/JSON Schema validated messages |
97
+ | [Compiling to a Single Binary](./compile-binary) | The `platformaticWasmPlugin()` fix for `bun build --compile` |
98
+ | [Examples & Troubleshooting](./examples) | End-to-end examples, IoC wiring, common errors |
628
99
 
629
- ## Pages
100
+ Start with [Producer](./producer) or [Consumer](./consumer) if you're wiring up your first topic; start with [Compiling to a Single Binary](./compile-binary) if an existing app just started throwing `ENOENT: native.wasm` after a `bun build --compile`.
630
101
 
631
- - **[Producer](./producer)** -- Producer helper, transactions, and full `@platformatic/kafka` Producer API reference
632
- - **[Consumer](./consumer)** -- Consumer helper, message callbacks, lag monitoring, and full Consumer API reference
633
- - **[Admin](./admin)** -- Admin helper and full Admin API reference
634
- - **[Schema Registry](./schema-registry)** -- Schema registry helper for Avro/Protobuf/JSON Schema validation
635
- - **[Examples & Troubleshooting](./examples)** -- Complete examples, IoC integration, and troubleshooting guide
102
+ ## See also
636
103
 
637
- ## See Also
104
+ - [Queue Helpers](../queue/) - BullMQ, MQTT, and the in-memory queue: the other three queueing backends
105
+ - [Redis Helper](../redis/) - connection management used elsewhere in the helpers package
106
+ - [Kafka Helpers Enhancement](/changelogs/2026-03-12-kafka-helpers-enhancement) / [Kafka Helpers Refactor](/changelogs/2026-03-10-kafka-helpers-refactor) - changelog history for this module
107
+ - [@platformatic/kafka](https://github.com/platformatic/kafka) - the underlying Kafka client library
108
+ - [Apache Kafka Documentation](https://kafka.apache.org/documentation/) - official Kafka docs
109
+ - [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848) - the new consumer group protocol
638
110
 
639
- - **Other Helpers:**
640
- - [Queue Helper](../queue/) -- BullMQ, MQTT, and in-memory queues
641
- - [Redis Helper](../redis/) -- Redis connection management
111
+ **Files:**
642
112
 
643
- - **External Resources:**
644
- - [@platformatic/kafka](https://github.com/platformatic/kafka) -- Underlying Kafka client library
645
- - [Apache Kafka Documentation](https://kafka.apache.org/documentation/) -- Official Kafka docs
646
- - [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848) -- New consumer group protocol
113
+ - [`packages/helpers/src/modules/queue/kafka/base.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/base.ts) - `BaseKafkaHelper`, health tracking, broker events
114
+ - [`packages/helpers/src/modules/queue/kafka/index.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/index.ts) - the `/kafka` sub-path barrel
115
+ - [`packages/helpers/src/modules/queue/kafka/common/constants.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/common/constants.ts) - `KafkaDefaults`, `KafkaAcks`, `KafkaGroupProtocol`, `KafkaHealthStatuses`, `KafkaClientEvents`
116
+ - [`packages/helpers/src/modules/queue/kafka/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/common/types.ts) - every `IKafka*` / `TKafka*` type