@venizia/ignis-docs 0.1.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 (148) 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 +83 -67
  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 +31 -17
  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 +98 -0
  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 -607
  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/datasources.md +13 -20
  89. package/content/guides/core-concepts/persistent/index.md +2 -4
  90. package/content/guides/core-concepts/persistent/models.md +1 -1
  91. package/content/guides/core-concepts/persistent/postgres-drivers.md +59 -25
  92. package/content/guides/core-concepts/persistent/search-meilisearch.md +3 -1
  93. package/content/guides/core-concepts/persistent/search-typesense.md +7 -5
  94. package/content/guides/core-concepts/persistent/transactions.md +1 -1
  95. package/content/guides/core-concepts/secrets-vault.md +177 -0
  96. package/content/guides/core-concepts/services.md +1 -1
  97. package/content/guides/migrations/redis-helpers-migration.md +1 -1
  98. package/content/guides/migrations/unified-connectors-migration.md +2 -2
  99. package/content/guides/tutorials/building-a-crud-api.md +9 -13
  100. package/content/guides/tutorials/ecommerce-api.md +10 -15
  101. package/content/guides/tutorials/realtime-chat.md +7 -7
  102. package/content/references/base/application.md +1 -1
  103. package/content/references/base/connectors.md +79 -136
  104. package/content/references/base/datasources-reference.md +599 -0
  105. package/content/references/base/datasources.md +85 -447
  106. package/content/references/base/dependency-injection.md +17 -39
  107. package/content/references/base/filter-system/application-usage.md +69 -121
  108. package/content/references/base/filter-system/array-operators.md +12 -0
  109. package/content/references/base/filter-system/comparison-operators.md +12 -0
  110. package/content/references/base/filter-system/default-filter.md +136 -348
  111. package/content/references/base/filter-system/fields-order-pagination.md +38 -16
  112. package/content/references/base/filter-system/index.md +106 -257
  113. package/content/references/base/filter-system/json-filtering.md +12 -2
  114. package/content/references/base/filter-system/list-operators.md +16 -2
  115. package/content/references/base/filter-system/logical-operators.md +13 -0
  116. package/content/references/base/filter-system/null-operators.md +13 -0
  117. package/content/references/base/filter-system/pattern-matching.md +12 -0
  118. package/content/references/base/filter-system/quick-reference.md +11 -2
  119. package/content/references/base/filter-system/range-operators.md +12 -0
  120. package/content/references/base/filter-system/tips.md +70 -133
  121. package/content/references/base/filter-system/use-cases.md +156 -233
  122. package/content/references/base/middlewares.md +35 -21
  123. package/content/references/base/models-reference.md +886 -0
  124. package/content/references/base/models.md +80 -1452
  125. package/content/references/base/repositories/advanced.md +156 -192
  126. package/content/references/base/repositories/index.md +77 -650
  127. package/content/references/base/repositories/mixins.md +22 -18
  128. package/content/references/base/repositories/relations.md +123 -171
  129. package/content/references/base/repositories/soft-deletable.md +58 -56
  130. package/content/references/base/secrets.md +263 -0
  131. package/content/references/base/services.md +2 -2
  132. package/content/references/configuration/environment-variables.md +51 -5
  133. package/content/references/configuration/index.md +49 -31
  134. package/content/references/quick-reference.md +3 -16
  135. package/content/references/utilities/crypto.md +35 -76
  136. package/content/references/utilities/date.md +33 -73
  137. package/content/references/utilities/index.md +1 -1
  138. package/content/references/utilities/jsx-reference.md +298 -0
  139. package/content/references/utilities/jsx.md +82 -525
  140. package/content/references/utilities/module.md +29 -62
  141. package/content/references/utilities/parse.md +34 -64
  142. package/content/references/utilities/performance.md +33 -58
  143. package/content/references/utilities/promise.md +28 -62
  144. package/content/references/utilities/request.md +57 -218
  145. package/content/references/utilities/schema.md +43 -137
  146. package/content/references/utilities/statuses-reference.md +361 -0
  147. package/content/references/utilities/statuses.md +63 -667
  148. package/package.json +8 -8
@@ -1,643 +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
- ### Installation
92
-
93
- ```bash
94
- bun add @platformatic/kafka
95
- ```
96
-
97
- ## Architecture
98
-
99
- ### Class Hierarchy
100
-
101
- ```
102
- BaseHelper (scoped logging, identifier)
103
- +-- BaseKafkaHelper<TClient> (health tracking, broker events, graceful shutdown)
104
- | +-- KafkaProducerHelper<K,V,HK,HV>
105
- | +-- KafkaConsumerHelper<K,V,HK,HV>
106
- | +-- KafkaAdminHelper
107
- |
108
- +-- KafkaSchemaRegistryHelper<K,V,HK,HV> (no broker connection)
109
- ```
110
-
111
- ### BaseKafkaHelper
112
-
113
- All Kafka helpers (except schema registry) extend `BaseKafkaHelper<TClient>`, which provides:
114
-
115
- ```typescript
116
- abstract class BaseKafkaHelper<TClient extends Base<BaseOptions>> extends BaseHelper {
117
- // Health
118
- isHealthy(): boolean; // true when at least one broker is connected
119
- isReady(): boolean; // healthStatus === 'connected' (consumer overrides: + isActive())
120
- getHealthStatus(): TKafkaHealthStatus; // 'connected' | 'disconnected' | 'unknown'
121
- getConnectedBrokerCount(): number; // number of currently connected brokers
122
-
123
- // Shutdown (used by subclasses)
124
- protected closeClient(): Promise<void>;
125
- protected gracefulCloseClient(): Promise<void>; // races closeClient vs shutdownTimeout
126
- protected resetHealthState(): void; // clears broker tracking + sets 'disconnected'
127
- }
128
- ```
129
-
130
- 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`.
131
-
132
- Health status transitions automatically via broker events:
133
- - `client:broker:connect` -> adds broker, sets `healthStatus` to `'connected'`
134
- - `client:broker:disconnect` -> removes broker, sets `healthStatus` to `'disconnected'` only when all brokers are gone
135
- - `client:broker:failed` -> removes broker, sets `healthStatus` to `'disconnected'` only when all brokers are gone
136
- - `close()` -> clears all brokers, sets `healthStatus` to `'disconnected'`
137
-
138
- ## Connection Options
139
-
140
- All three helpers share a common base interface `IKafkaConnectionOptions` which extends `@platformatic/kafka`'s `ConnectionOptions`.
141
-
142
- ```typescript
143
- interface IKafkaConnectionOptions extends ConnectionOptions {
144
- bootstrapBrokers: string[];
145
- clientId: string;
146
- retries?: number; // Default: 3
147
- retryDelay?: number; // Default: 1000ms
148
- }
149
- ```
150
-
151
- ### Full Options Table
152
-
153
- | Option | Type | Default | Description |
154
- |--------|------|---------|-------------|
155
- | `bootstrapBrokers` | `string[]` | -- | Kafka broker addresses (`host:port`). **Required** |
156
- | `clientId` | `string` | -- | Unique client identifier. **Required** |
157
- | `retries` | `number` | `3` | Number of connection retries before failing |
158
- | `retryDelay` | `number` | `1000` | Delay between retries in milliseconds |
159
- | `sasl` | `SASLOptions` | -- | SASL authentication configuration |
160
- | `tls` | `TLSConnectionOptions` | -- | TLS/SSL connection options |
161
- | `ssl` | `TLSConnectionOptions` | -- | Alias for `tls` |
162
- | `connectTimeout` | `number` | -- | TCP connection timeout in milliseconds |
163
- | `requestTimeout` | `number` | -- | Kafka request timeout in milliseconds |
164
-
165
- ### Shared Helper Options
166
-
167
- These options are available on all three helpers (`IKafkaProducerOptions`, `IKafkaConsumerOptions`, `IKafkaAdminOptions`):
168
-
169
- | Option | Type | Default | Description |
170
- |--------|------|---------|-------------|
171
- | `identifier` | `string` | `'kafka-{type}'` | Scoped logging identifier |
172
- | `shutdownTimeout` | `number` | `30000` | Graceful shutdown timeout in ms |
173
- | `onBrokerConnect` | `TKafkaBrokerEventCallback` | -- | Called when broker connects |
174
- | `onBrokerDisconnect` | `TKafkaBrokerEventCallback` | -- | Called when broker disconnects |
175
-
176
- ### SASL Authentication
177
-
178
- `@platformatic/kafka` supports five SASL mechanisms:
179
-
180
- | Mechanism | Use Case |
181
- |-----------|----------|
182
- | `PLAIN` | Simple username/password (use with TLS in production) |
183
- | `SCRAM-SHA-256` | Challenge-response, password never sent in plaintext |
184
- | `SCRAM-SHA-512` | Same as SHA-256 with stronger hash |
185
- | `OAUTHBEARER` | Token-based (Azure Event Hubs, Confluent Cloud) |
186
- | `GSSAPI` | Kerberos authentication |
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
+ ---
187
6
 
188
- ```typescript
189
- interface SASLOptions {
190
- mechanism: 'PLAIN' | 'SCRAM-SHA-256' | 'SCRAM-SHA-512' | 'OAUTHBEARER' | 'GSSAPI';
191
- username?: string | CredentialProvider;
192
- password?: string | CredentialProvider;
193
- token?: string | CredentialProvider;
194
- oauthBearerExtensions?: Record<string, string> | CredentialProvider<Record<string, string>>;
195
- authenticate?: SASLCustomAuthenticator;
196
- }
197
- ```
198
-
199
- #### SCRAM-SHA-512 Example
200
-
201
- ```typescript
202
- const helper = KafkaConsumerHelper.newInstance({
203
- bootstrapBrokers: ['broker1:9092', 'broker2:9092', 'broker3:9092'],
204
- clientId: 'my-consumer',
205
- groupId: 'my-group',
206
- sasl: {
207
- mechanism: 'SCRAM-SHA-512',
208
- username: 'kafka-user',
209
- password: 'kafka-password',
210
- },
211
- connectTimeout: 30_000,
212
- requestTimeout: 30_000,
213
- onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}:${broker.port}`),
214
- });
215
- ```
216
-
217
- #### OAUTHBEARER Example
218
-
219
- ```typescript
220
- const helper = KafkaProducerHelper.newInstance({
221
- bootstrapBrokers: ['pkc-xxxxx.us-west-2.aws.confluent.cloud:9092'],
222
- clientId: 'my-producer',
223
- sasl: {
224
- mechanism: 'OAUTHBEARER',
225
- token: async () => {
226
- const response = await fetch('https://auth.example.com/token', { method: 'POST' });
227
- const { access_token } = await response.json();
228
- return access_token;
229
- },
230
- },
231
- tls: true,
232
- });
233
- ```
234
-
235
- #### TLS Without SASL
236
-
237
- ```typescript
238
- const helper = KafkaProducerHelper.newInstance({
239
- bootstrapBrokers: ['broker:9093'],
240
- clientId: 'my-producer',
241
- tls: {
242
- ca: fs.readFileSync('/path/to/ca.pem'),
243
- cert: fs.readFileSync('/path/to/client-cert.pem'),
244
- key: fs.readFileSync('/path/to/client-key.pem'),
245
- },
246
- });
247
- ```
248
-
249
- ## Serialization & Deserialization
250
-
251
- `@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.
252
-
253
- ### Built-in Serializers
254
-
255
- | Export | Type | Description |
256
- |--------|------|-------------|
257
- | `stringSerializer` | `Serializer<string>` | `string -> Buffer` (UTF-8) |
258
- | `stringDeserializer` | `Deserializer<string>` | `Buffer -> string` (UTF-8) |
259
- | `jsonSerializer` | `Serializer<T>` | `object -> Buffer` (JSON.stringify + UTF-8) |
260
- | `jsonDeserializer` | `Deserializer<T>` | `Buffer -> object` (UTF-8 + JSON.parse) |
261
- | `stringSerializers` | `Serializers<string, string, string, string>` | All four positions as string |
262
- | `stringDeserializers` | `Deserializers<string, string, string, string>` | All four positions as string |
7
+ # Kafka
263
8
 
264
- ### 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.
265
10
 
266
- | Export | Signature | Description |
267
- |--------|-----------|-------------|
268
- | `serializersFrom(s)` | `<T>(s: Serializer<T>) => Serializers<T, T, T, T>` | Create full serializers from a single serializer |
269
- | `deserializersFrom(d)` | `<T>(d: Deserializer<T>) => Deserializers<T, T, T, T>` | Create full deserializers from a single deserializer |
11
+ ## In one example
270
12
 
271
- ### String Serialization
13
+ The smallest real use: create a producer, send a message through the underlying client, and close it.
272
14
 
273
15
  ```typescript
274
- import { stringSerializers, stringDeserializers } from '@platformatic/kafka';
16
+ import { KafkaProducerHelper } from '@venizia/ignis-helpers/kafka';
17
+ import { stringSerializers } from '@platformatic/kafka';
275
18
 
276
19
  const producer = KafkaProducerHelper.newInstance({
277
20
  bootstrapBrokers: ['localhost:9092'],
278
- clientId: 'my-producer',
21
+ clientId: 'order-producer',
279
22
  serializers: stringSerializers,
280
23
  });
281
24
 
282
- const consumer = KafkaConsumerHelper.newInstance({
283
- bootstrapBrokers: ['localhost:9092'],
284
- clientId: 'my-consumer',
285
- groupId: 'my-group',
286
- deserializers: stringDeserializers,
287
- onMessage: async ({ message }) => {
288
- console.log(message.key, message.value); // both strings
289
- },
290
- });
291
- ```
292
-
293
- ### JSON Serialization
294
-
295
- ```typescript
296
- import {
297
- jsonSerializer, jsonDeserializer,
298
- stringSerializer, stringDeserializer,
299
- serializersFrom, deserializersFrom,
300
- } from '@platformatic/kafka';
301
-
302
- const producer = KafkaProducerHelper.newInstance({
303
- bootstrapBrokers: ['localhost:9092'],
304
- clientId: 'my-producer',
305
- serializers: { ...serializersFrom(jsonSerializer), key: stringSerializer },
306
- });
307
-
308
25
  await producer.getProducer().send({
309
- messages: [{
310
- topic: 'orders',
311
- key: 'order-123',
312
- value: { id: '123', status: 'created', amount: 99 },
313
- }],
26
+ messages: [{ topic: 'orders', key: 'order-1', value: JSON.stringify({ status: 'created' }) }],
314
27
  });
315
28
 
316
- const consumer = KafkaConsumerHelper.newInstance({
317
- bootstrapBrokers: ['localhost:9092'],
318
- clientId: 'my-consumer',
319
- groupId: 'my-group',
320
- deserializers: { ...deserializersFrom(jsonDeserializer), key: stringDeserializer },
321
- onMessage: async ({ message }) => {
322
- console.log(message.value.id, message.value.status); // typed object
323
- },
324
- });
29
+ await producer.close();
325
30
  ```
326
31
 
327
- ### Schema Registry Serialization
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.
328
33
 
329
- For schema-validated serialization (Avro, Protobuf, JSON Schema), use the schema registry helper:
34
+ ## How it works
330
35
 
331
- ```typescript
332
- const registry = KafkaSchemaRegistryHelper.newInstance({
333
- url: 'http://localhost:8081',
334
- });
36
+ - **Four helpers, one job each.**
335
37
 
336
- const producer = KafkaProducerHelper.newInstance({
337
- bootstrapBrokers: ['localhost:9092'],
338
- clientId: 'my-producer',
339
- registry: registry.getRegistry(),
340
- });
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) |
341
44
 
342
- const consumer = KafkaConsumerHelper.newInstance({
343
- bootstrapBrokers: ['localhost:9092'],
344
- clientId: 'my-consumer',
345
- groupId: 'my-group',
346
- registry: registry.getRegistry(),
347
- onMessage: async ({ message }) => {
348
- // message.value is auto-deserialized using registered schema
349
- },
350
- });
351
- ```
45
+ - **The three connected helpers share an identical health & close API**, regardless of which client they wrap:
352
46
 
353
- See **[Schema Registry](./schema-registry)** for full documentation.
47
+ ```typescript
48
+ const producer = KafkaProducerHelper.newInstance({ bootstrapBrokers, clientId });
49
+ const consumer = KafkaConsumerHelper.newInstance({ bootstrapBrokers, clientId, groupId });
50
+ const admin = KafkaAdminHelper.newInstance({ bootstrapBrokers, clientId });
354
51
 
355
- ## Generic Type Parameters
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'
356
55
 
357
- All helpers (and their option interfaces) support generic type parameters controlling the serialization types:
56
+ await Promise.all([producer.close(), consumer.close(), admin.close()]); // graceful, force fallback
57
+ ```
358
58
 
359
- ```typescript
360
- class KafkaProducerHelper<
361
- KeyType = string,
362
- ValueType = string,
363
- HeaderKeyType = string,
364
- HeaderValueType = string,
365
- >
366
- ```
367
-
368
- | Parameter | Default | Description |
369
- |-----------|---------|-------------|
370
- | `KeyType` | `string` | Message key type after serialization/deserialization |
371
- | `ValueType` | `string` | Message value type after serialization/deserialization |
372
- | `HeaderKeyType` | `string` | Header key type |
373
- | `HeaderValueType` | `string` | Header value type |
374
-
375
- > [!NOTE]
376
- > `@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`.
377
-
378
- ```typescript
379
- // Default: string types (most common)
380
- const helper = KafkaProducerHelper.newInstance({ ... });
381
-
382
- // Custom: string keys, JSON object values
383
- const helper = KafkaProducerHelper.newInstance<string, MyEvent, string, string>({
384
- serializers: { ...serializersFrom(jsonSerializer), key: stringSerializer },
385
- ...
386
- });
387
- ```
388
-
389
- ## Constants
390
-
391
- ### KafkaDefaults
392
-
393
- Centralized default values used by all helpers.
394
-
395
- ```typescript
396
- import { KafkaDefaults } from '@venizia/ignis-helpers/kafka';
397
- ```
398
-
399
- | Constant | Value | Scope | Description |
400
- |----------|-------|-------|-------------|
401
- | `RETRIES` | `3` | Shared | Connection retry count |
402
- | `RETRY_DELAY` | `1000` | Shared | Retry delay in ms |
403
- | `SHUTDOWN_TIMEOUT` | `30000` | Shared | Graceful shutdown timeout in ms |
404
- | `STRICT` | `true` | Producer | Fail on unknown topics |
405
- | `AUTOCREATE_TOPICS` | `false` | Producer | Auto-create topics on produce |
406
- | `AUTOCOMMIT` | `false` | Consumer | Auto-commit offsets |
407
- | `SESSION_TIMEOUT` | `60000` | Consumer | Session timeout in ms |
408
- | `HEARTBEAT_INTERVAL` | `10000` | Consumer | Heartbeat interval in ms |
409
- | `HIGH_WATER_MARK` | `1024` | Consumer | Stream buffer size (messages) |
410
- | `MIN_BYTES` | `1` | Consumer | Min bytes per fetch |
411
- | `METADATA_MAX_AGE` | `300000` | Consumer | Metadata cache TTL in ms |
412
- | `GROUP_PROTOCOL` | `'classic'` | Consumer | Default group protocol |
413
- | `CONSUME_MODE` | `'committed'` | Consumer | Default consume mode |
414
- | `CONSUME_FALLBACK_MODE` | `'latest'` | Consumer | Default consume fallback mode |
415
- | `LAG_MONITOR_INTERVAL` | `30000` | Consumer | Lag monitoring poll interval in ms |
416
-
417
- ### KafkaHealthStatuses
418
-
419
- Health status values used by all Kafka helpers.
420
-
421
- ```typescript
422
- import { KafkaHealthStatuses } from '@venizia/ignis-helpers/kafka';
423
- ```
424
-
425
- | Constant | Value | Description |
426
- |----------|-------|-------------|
427
- | `CONNECTED` | `'connected'` | Broker connection established |
428
- | `DISCONNECTED` | `'disconnected'` | Broker connection lost or closed |
429
- | `UNKNOWN` | `'unknown'` | Initial state before first broker event |
430
-
431
- ### KafkaClientEvents
432
-
433
- Event name constants for `@platformatic/kafka` event emitters.
434
-
435
- ```typescript
436
- import { KafkaClientEvents } from '@venizia/ignis-helpers/kafka';
437
- ```
438
-
439
- | Constant | Value | Scope |
440
- |----------|-------|-------|
441
- | `BROKER_CONNECT` | `'client:broker:connect'` | All clients |
442
- | `BROKER_DISCONNECT` | `'client:broker:disconnect'` | All clients |
443
- | `BROKER_FAILED` | `'client:broker:failed'` | All clients |
444
- | `CONSUMER_GROUP_JOIN` | `'consumer:group:join'` | Consumer |
445
- | `CONSUMER_GROUP_LEAVE` | `'consumer:group:leave'` | Consumer |
446
- | `CONSUMER_GROUP_REBALANCE` | `'consumer:group:rebalance'` | Consumer |
447
- | `CONSUMER_HEARTBEAT_ERROR` | `'consumer:heartbeat:error'` | Consumer |
448
- | `CONSUMER_LAG` | `'consumer:lag'` | Consumer |
449
- | `CONSUMER_LAG_ERROR` | `'consumer:lag:error'` | Consumer |
450
- | `STREAM_DATA` | `'data'` | Stream |
451
- | `STREAM_ERROR` | `'error'` | Stream |
452
-
453
- ### KafkaAcks
454
-
455
- Producer acknowledgment levels.
456
-
457
- ```typescript
458
- import { KafkaAcks } from '@venizia/ignis-helpers/kafka';
459
- ```
460
-
461
- | Constant | Value | Description | Trade-off |
462
- |----------|-------|-------------|-----------|
463
- | `NONE` | `0` | No acknowledgment -- fire-and-forget | Fastest, no durability guarantee |
464
- | `LEADER` | `1` | Leader broker acknowledges | Fast, leader-durable |
465
- | `ALL` | `-1` | All in-sync replicas acknowledge | Slowest, fully durable |
466
-
467
- ### KafkaGroupProtocol
468
-
469
- Consumer group protocol versions.
470
-
471
- ```typescript
472
- import { KafkaGroupProtocol } from '@venizia/ignis-helpers/kafka';
473
- ```
474
-
475
- | Constant | Value | Description |
476
- |----------|-------|-------------|
477
- | `CLASSIC` | `'classic'` | Classic consumer group protocol (default, all Kafka versions) |
478
- | `CONSUMER` | `'consumer'` | New consumer group protocol -- KIP-848 (Kafka 3.7+) |
479
-
480
- ### Derived Types
481
-
482
- ```typescript
483
- import type { TKafkaAcks, TKafkaGroupProtocol, TKafkaHealthStatus } from '@venizia/ignis-helpers/kafka';
484
-
485
- // TKafkaAcks = 0 | 1 | -1
486
- // TKafkaGroupProtocol = 'classic' | 'consumer'
487
- // TKafkaHealthStatus = 'connected' | 'disconnected' | 'unknown'
488
- ```
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
+ ```
489
68
 
490
- ## 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).
491
76
 
492
- `@platformatic/kafka` supports five compression algorithms:
77
+ **Exported constants** (`@venizia/ignis-helpers/kafka`):
493
78
 
494
- | Algorithm | Value | Description |
495
- |-----------|-------|-------------|
496
- | None | `'none'` | No compression (default) |
497
- | GZIP | `'gzip'` | Good compression ratio, moderate CPU |
498
- | Snappy | `'snappy'` | Fast compression, moderate ratio |
499
- | LZ4 | `'lz4'` | Very fast, good for high-throughput |
500
- | 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()` |
501
86
 
502
- ```typescript
503
- const helper = KafkaProducerHelper.newInstance({
504
- bootstrapBrokers: ['localhost:9092'],
505
- clientId: 'my-producer',
506
- serializers: stringSerializers,
507
- compression: 'zstd',
508
- });
509
-
510
- // Override per-send
511
- await helper.getProducer().send({
512
- messages: [{ topic: 'logs', key: 'l1', value: largePayload }],
513
- compression: 'lz4',
514
- });
515
- ```
516
-
517
- ## Quick Usage Comparison
518
-
519
- ### Construction
520
-
521
- ```typescript
522
- // Admin
523
- const admin = KafkaAdminHelper.newInstance({
524
- bootstrapBrokers: ['127.0.0.1:29092'],
525
- clientId: 'my-admin',
526
- onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}`),
527
- onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
528
- });
529
-
530
- // Producer
531
- const producer = KafkaProducerHelper.newInstance({
532
- bootstrapBrokers: ['127.0.0.1:29092'],
533
- clientId: 'my-producer',
534
- acks: -1,
535
- idempotent: true,
536
- transactionalId: 'my-tx',
537
- onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}`),
538
- onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
539
- });
540
-
541
- // Consumer
542
- const consumer = KafkaConsumerHelper.newInstance({
543
- bootstrapBrokers: ['127.0.0.1:29092'],
544
- clientId: 'my-consumer',
545
- groupId: 'my-group',
546
- onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}`),
547
- onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
548
- onMessage: async ({ message }) => {
549
- console.log('Received:', message.value);
550
- await message.commit();
551
- },
552
- onMessageDone: ({ message }) => console.log('Done:', message.key),
553
- onMessageError: ({ error, message }) => console.error('Error:', error),
554
- onGroupJoin: ({ groupId, memberId }) => console.log(`Joined ${groupId}`),
555
- onGroupLeave: ({ groupId }) => console.log(`Left ${groupId}`),
556
- onGroupRebalance: ({ groupId }) => console.log(`Rebalance ${groupId}`),
557
- onHeartbeatError: ({ error }) => console.error('Heartbeat:', error),
558
- onLag: ({ lag }) => console.log('Lag:', lag),
559
- onLagError: ({ error }) => console.error('Lag error:', error),
560
- });
561
- ```
562
-
563
- ### Core Operations
564
-
565
- | Admin | Producer | Consumer |
566
- |-------|----------|----------|
567
- | `admin.getAdmin()` | `producer.getProducer()` | `consumer.getConsumer()` |
568
- | -- | `producer.getProducer().send(...)` | `await consumer.start({ topics: ['t1'] })` |
569
- | -- | `await producer.runInTransaction(async ({ send, addConsumer, addOffset }) => { ... })` | `consumer.startLagMonitoring({ topics: ['t1'], interval: 10_000 })` |
570
- | -- | -- | `consumer.stopLagMonitoring()` |
571
- | -- | -- | `consumer.getStream()` |
572
-
573
- ### Health Checks
574
-
575
- ```typescript
576
- // All three -- identical API
577
- helper.isHealthy(); // true when at least one broker connected
578
- helper.isReady(); // Admin/Producer: same as isHealthy()
579
- // Consumer: isHealthy() + consumer.isActive()
580
- helper.getHealthStatus(); // 'connected' | 'disconnected' | 'unknown'
581
- ```
582
-
583
- ### Shutdown
584
-
585
- ```typescript
586
- // All three -- identical API
587
- await helper.close(); // graceful (timeout -> force fallback)
588
- await helper.close({ isForce: true }); // immediate force close
589
- ```
590
-
591
- ### With Schema Registry
592
-
593
- ```typescript
594
- const registry = KafkaSchemaRegistryHelper.newInstance({ url: 'http://localhost:8081' });
595
-
596
- const producer = KafkaProducerHelper.newInstance({
597
- ...,
598
- registry: registry.getRegistry(),
599
- // or use registry.getSerializers() for manual serializer config
600
- });
601
-
602
- const consumer = KafkaConsumerHelper.newInstance({
603
- ...,
604
- registry: registry.getRegistry(),
605
- // or use registry.getDeserializers() for manual deserializer config
606
- });
607
- ```
608
-
609
- ### Transaction (Producer Only)
610
-
611
- ```typescript
612
- const result = await producer.runInTransaction(async ({ send, addConsumer, addOffset }) => {
613
- // Send messages within transaction
614
- const result = await send({
615
- messages: [{ topic: 'orders', key: 'o1', value: '{"status":"created"}' }],
616
- });
87
+ ## Pages
617
88
 
618
- // Optionally add consumer for exactly-once semantics
619
- await addConsumer(consumer.getConsumer());
620
- await addOffset(message);
89
+ Each class, and the one build-time gotcha, gets its own page:
621
90
 
622
- return result;
623
- });
624
- ```
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 |
625
99
 
626
- ## 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`.
627
101
 
628
- - **[Producer](./producer)** -- Producer helper, transactions, and full `@platformatic/kafka` Producer API reference
629
- - **[Consumer](./consumer)** -- Consumer helper, message callbacks, lag monitoring, and full Consumer API reference
630
- - **[Admin](./admin)** -- Admin helper and full Admin API reference
631
- - **[Schema Registry](./schema-registry)** -- Schema registry helper for Avro/Protobuf/JSON Schema validation
632
- - **[Examples & Troubleshooting](./examples)** -- Complete examples, IoC integration, and troubleshooting guide
102
+ ## See also
633
103
 
634
- ## 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
635
110
 
636
- - **Other Helpers:**
637
- - [Queue Helper](../queue/) -- BullMQ, MQTT, and in-memory queues
638
- - [Redis Helper](../redis/) -- Redis connection management
111
+ **Files:**
639
112
 
640
- - **External Resources:**
641
- - [@platformatic/kafka](https://github.com/platformatic/kafka) -- Underlying Kafka client library
642
- - [Apache Kafka Documentation](https://kafka.apache.org/documentation/) -- Official Kafka docs
643
- - [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