@venizia/ignis-docs 0.0.7-2 → 0.0.8-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 (161) hide show
  1. package/dist/mcp-server/common/paths.d.ts +4 -2
  2. package/dist/mcp-server/common/paths.d.ts.map +1 -1
  3. package/dist/mcp-server/common/paths.js +8 -6
  4. package/dist/mcp-server/common/paths.js.map +1 -1
  5. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts +1 -1
  6. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -1
  7. package/dist/mcp-server/tools/docs/get-document-content.tool.js +7 -7
  8. package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +3 -3
  9. package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +1 -1
  10. package/dist/mcp-server/tools/docs/get-package-overview.tool.js +1 -1
  11. package/package.json +1 -1
  12. package/wiki/best-practices/api-usage-examples.md +9 -9
  13. package/wiki/best-practices/architectural-patterns.md +19 -3
  14. package/wiki/best-practices/architecture-decisions.md +6 -6
  15. package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
  16. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  17. package/wiki/best-practices/code-style-standards/function-patterns.md +2 -2
  18. package/wiki/best-practices/code-style-standards/index.md +2 -2
  19. package/wiki/best-practices/code-style-standards/naming-conventions.md +1 -1
  20. package/wiki/best-practices/code-style-standards/route-definitions.md +4 -4
  21. package/wiki/best-practices/data-modeling.md +1 -1
  22. package/wiki/best-practices/deployment-strategies.md +1 -1
  23. package/wiki/best-practices/error-handling.md +2 -2
  24. package/wiki/best-practices/performance-optimization.md +3 -3
  25. package/wiki/best-practices/security-guidelines.md +2 -2
  26. package/wiki/best-practices/troubleshooting-tips.md +1 -1
  27. package/wiki/{references → extensions}/components/authentication/api.md +12 -20
  28. package/wiki/{references → extensions}/components/authentication/errors.md +1 -1
  29. package/wiki/{references → extensions}/components/authentication/index.md +5 -8
  30. package/wiki/{references → extensions}/components/authentication/usage.md +20 -36
  31. package/wiki/{references → extensions}/components/authorization/api.md +62 -13
  32. package/wiki/{references → extensions}/components/authorization/errors.md +12 -7
  33. package/wiki/{references → extensions}/components/authorization/index.md +93 -6
  34. package/wiki/{references → extensions}/components/authorization/usage.md +42 -4
  35. package/wiki/{references → extensions}/components/health-check.md +5 -4
  36. package/wiki/{references → extensions}/components/index.md +2 -0
  37. package/wiki/{references → extensions}/components/mail/index.md +1 -1
  38. package/wiki/{references → extensions}/components/request-tracker.md +1 -1
  39. package/wiki/{references → extensions}/components/socket-io/api.md +2 -2
  40. package/wiki/{references → extensions}/components/socket-io/errors.md +2 -0
  41. package/wiki/{references → extensions}/components/socket-io/index.md +24 -20
  42. package/wiki/{references → extensions}/components/socket-io/usage.md +2 -2
  43. package/wiki/{references → extensions}/components/static-asset/api.md +14 -15
  44. package/wiki/{references → extensions}/components/static-asset/errors.md +3 -1
  45. package/wiki/{references → extensions}/components/static-asset/index.md +158 -89
  46. package/wiki/{references → extensions}/components/static-asset/usage.md +8 -5
  47. package/wiki/{references → extensions}/components/swagger.md +3 -3
  48. package/wiki/{references → extensions}/components/template/index.md +4 -4
  49. package/wiki/{references → extensions}/components/template/setup-page.md +1 -1
  50. package/wiki/{references → extensions}/components/template/single-page.md +1 -1
  51. package/wiki/{references → extensions}/components/websocket/api.md +7 -6
  52. package/wiki/{references → extensions}/components/websocket/errors.md +17 -3
  53. package/wiki/{references → extensions}/components/websocket/index.md +17 -11
  54. package/wiki/{references → extensions}/components/websocket/usage.md +2 -2
  55. package/wiki/{references → extensions}/helpers/crypto/index.md +1 -1
  56. package/wiki/{references → extensions}/helpers/env/index.md +9 -5
  57. package/wiki/{references → extensions}/helpers/error/index.md +2 -7
  58. package/wiki/{references → extensions}/helpers/index.md +18 -6
  59. package/wiki/{references → extensions}/helpers/kafka/admin.md +33 -16
  60. package/wiki/extensions/helpers/kafka/consumer.md +384 -0
  61. package/wiki/extensions/helpers/kafka/examples.md +361 -0
  62. package/wiki/extensions/helpers/kafka/index.md +639 -0
  63. package/wiki/{references → extensions}/helpers/kafka/producer.md +100 -96
  64. package/wiki/extensions/helpers/kafka/schema-registry.md +214 -0
  65. package/wiki/{references → extensions}/helpers/logger/index.md +2 -2
  66. package/wiki/{references → extensions}/helpers/queue/index.md +400 -4
  67. package/wiki/{references → extensions}/helpers/storage/api.md +170 -10
  68. package/wiki/{references → extensions}/helpers/storage/index.md +44 -8
  69. package/wiki/{references → extensions}/helpers/template/index.md +1 -1
  70. package/wiki/{references → extensions}/helpers/testing/index.md +4 -4
  71. package/wiki/{references → extensions}/helpers/types/index.md +63 -16
  72. package/wiki/{references → extensions}/helpers/websocket/index.md +1 -1
  73. package/wiki/extensions/index.md +48 -0
  74. package/wiki/guides/core-concepts/application/bootstrapping.md +55 -37
  75. package/wiki/guides/core-concepts/application/index.md +95 -35
  76. package/wiki/guides/core-concepts/components-guide.md +23 -19
  77. package/wiki/guides/core-concepts/components.md +34 -10
  78. package/wiki/guides/core-concepts/dependency-injection.md +99 -34
  79. package/wiki/guides/core-concepts/grpc-controllers.md +295 -0
  80. package/wiki/guides/core-concepts/persistent/datasources.md +27 -8
  81. package/wiki/guides/core-concepts/persistent/models.md +43 -1
  82. package/wiki/guides/core-concepts/persistent/repositories.md +75 -8
  83. package/wiki/guides/core-concepts/persistent/transactions.md +38 -8
  84. package/wiki/guides/core-concepts/{controllers.md → rest-controllers.md} +30 -33
  85. package/wiki/guides/core-concepts/services.md +19 -5
  86. package/wiki/guides/get-started/5-minute-quickstart.md +6 -7
  87. package/wiki/guides/get-started/philosophy.md +1 -1
  88. package/wiki/guides/index.md +2 -2
  89. package/wiki/guides/reference/glossary.md +7 -7
  90. package/wiki/guides/reference/mcp-docs-server.md +1 -1
  91. package/wiki/guides/tutorials/building-a-crud-api.md +2 -2
  92. package/wiki/guides/tutorials/complete-installation.md +17 -14
  93. package/wiki/guides/tutorials/ecommerce-api.md +18 -18
  94. package/wiki/guides/tutorials/realtime-chat.md +8 -8
  95. package/wiki/guides/tutorials/testing.md +2 -2
  96. package/wiki/index.md +4 -3
  97. package/wiki/references/base/application.md +341 -21
  98. package/wiki/references/base/bootstrapping.md +43 -13
  99. package/wiki/references/base/components.md +259 -8
  100. package/wiki/references/base/controllers.md +556 -253
  101. package/wiki/references/base/datasources.md +159 -79
  102. package/wiki/references/base/dependency-injection.md +299 -48
  103. package/wiki/references/base/filter-system/application-usage.md +18 -2
  104. package/wiki/references/base/filter-system/array-operators.md +14 -6
  105. package/wiki/references/base/filter-system/comparison-operators.md +9 -3
  106. package/wiki/references/base/filter-system/default-filter.md +28 -3
  107. package/wiki/references/base/filter-system/fields-order-pagination.md +17 -13
  108. package/wiki/references/base/filter-system/index.md +169 -11
  109. package/wiki/references/base/filter-system/json-filtering.md +51 -18
  110. package/wiki/references/base/filter-system/list-operators.md +4 -3
  111. package/wiki/references/base/filter-system/logical-operators.md +7 -2
  112. package/wiki/references/base/filter-system/null-operators.md +50 -0
  113. package/wiki/references/base/filter-system/quick-reference.md +82 -243
  114. package/wiki/references/base/filter-system/range-operators.md +7 -1
  115. package/wiki/references/base/filter-system/tips.md +34 -7
  116. package/wiki/references/base/filter-system/use-cases.md +6 -5
  117. package/wiki/references/base/grpc-controllers.md +984 -0
  118. package/wiki/references/base/index.md +32 -24
  119. package/wiki/references/base/middleware.md +347 -0
  120. package/wiki/references/base/models.md +390 -46
  121. package/wiki/references/base/providers.md +14 -14
  122. package/wiki/references/base/repositories/advanced.md +84 -69
  123. package/wiki/references/base/repositories/index.md +447 -12
  124. package/wiki/references/base/repositories/mixins.md +103 -98
  125. package/wiki/references/base/repositories/relations.md +129 -45
  126. package/wiki/references/base/repositories/soft-deletable.md +104 -23
  127. package/wiki/references/base/services.md +94 -14
  128. package/wiki/references/index.md +12 -10
  129. package/wiki/references/quick-reference.md +98 -65
  130. package/wiki/references/utilities/crypto.md +21 -4
  131. package/wiki/references/utilities/date.md +25 -7
  132. package/wiki/references/utilities/index.md +26 -24
  133. package/wiki/references/utilities/jsx.md +54 -54
  134. package/wiki/references/utilities/module.md +8 -6
  135. package/wiki/references/utilities/parse.md +16 -9
  136. package/wiki/references/utilities/performance.md +22 -7
  137. package/wiki/references/utilities/promise.md +19 -16
  138. package/wiki/references/utilities/request.md +48 -26
  139. package/wiki/references/utilities/schema.md +69 -6
  140. package/wiki/references/utilities/statuses.md +131 -140
  141. package/wiki/references/helpers/kafka/consumer.md +0 -473
  142. package/wiki/references/helpers/kafka/examples.md +0 -234
  143. package/wiki/references/helpers/kafka/index.md +0 -482
  144. /package/wiki/{references → extensions}/components/mail/api.md +0 -0
  145. /package/wiki/{references → extensions}/components/mail/errors.md +0 -0
  146. /package/wiki/{references → extensions}/components/mail/usage.md +0 -0
  147. /package/wiki/{references → extensions}/components/template/api-page.md +0 -0
  148. /package/wiki/{references → extensions}/components/template/errors-page.md +0 -0
  149. /package/wiki/{references → extensions}/components/template/usage-page.md +0 -0
  150. /package/wiki/{references → extensions}/helpers/cron/index.md +0 -0
  151. /package/wiki/{references → extensions}/helpers/inversion/index.md +0 -0
  152. /package/wiki/{references → extensions}/helpers/network/api.md +0 -0
  153. /package/wiki/{references → extensions}/helpers/network/index.md +0 -0
  154. /package/wiki/{references → extensions}/helpers/redis/index.md +0 -0
  155. /package/wiki/{references → extensions}/helpers/socket-io/api.md +0 -0
  156. /package/wiki/{references → extensions}/helpers/socket-io/index.md +0 -0
  157. /package/wiki/{references → extensions}/helpers/template/single-page.md +0 -0
  158. /package/wiki/{references → extensions}/helpers/uid/index.md +0 -0
  159. /package/wiki/{references → extensions}/helpers/websocket/api.md +0 -0
  160. /package/wiki/{references → extensions}/helpers/worker-thread/index.md +0 -0
  161. /package/wiki/{references → extensions}/src-details/mcp-server.md +0 -0
@@ -0,0 +1,384 @@
1
+ # Consumer
2
+
3
+ The `KafkaConsumerHelper` wraps `@platformatic/kafka`'s `Consumer` with health tracking, graceful shutdown, message callbacks, consumer group event callbacks, and lag monitoring.
4
+
5
+ ```typescript
6
+ class KafkaConsumerHelper<
7
+ KeyType = string,
8
+ ValueType = string,
9
+ HeaderKeyType = string,
10
+ HeaderValueType = string,
11
+ > extends BaseKafkaHelper<Consumer<KeyType, ValueType, HeaderKeyType, HeaderValueType>>
12
+ ```
13
+
14
+ ## Helper API
15
+
16
+ | Method | Signature | Description |
17
+ |--------|-----------|-------------|
18
+ | `newInstance(opts)` | `static newInstance<K,V,HK,HV>(opts): KafkaConsumerHelper<K,V,HK,HV>` | Factory method |
19
+ | `getConsumer()` | `(): Consumer<K,V,HK,HV>` | Access the underlying `Consumer` |
20
+ | `getStream()` | `(): MessagesStream \| null` | Get the active stream (after `start()`) |
21
+ | `start(opts)` | `(opts: IKafkaConsumeStartOptions): Promise<void>` | Start consuming (creates stream, wires callbacks) |
22
+ | `startLagMonitoring(opts)` | `(opts: { topics: string[]; interval?: number }): void` | Start periodic lag monitoring |
23
+ | `stopLagMonitoring()` | `(): void` | Stop lag monitoring |
24
+ | `isHealthy()` | `(): boolean` | `true` when broker connected |
25
+ | `isReady()` | `(): boolean` | `isHealthy()` **and** `consumer.isActive()` |
26
+ | `getHealthStatus()` | `(): TKafkaHealthStatus` | `'connected'` \| `'disconnected'` \| `'unknown'` |
27
+ | `close(opts?)` | `(opts?: { isForce?: boolean }): Promise<void>` | Stop lag, close stream, close consumer |
28
+
29
+ ## IKafkaConsumerOptions
30
+
31
+ ```typescript
32
+ interface IKafkaConsumerOptions<KeyType, ValueType, HeaderKeyType, HeaderValueType>
33
+ extends IKafkaConnectionOptions
34
+ ```
35
+
36
+ ### Consumer Configuration
37
+
38
+ | Option | Type | Default | Description |
39
+ |--------|------|---------|-------------|
40
+ | `groupId` | `string` | -- | Consumer group ID. **Required** |
41
+ | `identifier` | `string` | `'kafka-consumer'` | Scoped logging identifier |
42
+ | `deserializers` | `Partial<Deserializers<K,V,HK,HV>>` | -- | Key/value/header deserializers |
43
+ | `autocommit` | `boolean \| number` | `false` | Auto-commit offsets. `true` = default interval, `number` = custom ms |
44
+ | `sessionTimeout` | `number` | `30000` | Session timeout -- consumer removed from group if no heartbeat |
45
+ | `heartbeatInterval` | `number` | `3000` | Heartbeat interval -- must be less than `sessionTimeout` |
46
+ | `rebalanceTimeout` | `number` | `sessionTimeout` | Max time for rebalance. Defaults to the value of `sessionTimeout` |
47
+ | `highWaterMark` | `number` | `1024` | Stream buffer size (messages) |
48
+ | `minBytes` | `number` | `1` | Min bytes per fetch response |
49
+ | `maxBytes` | `number` | -- | Max bytes per fetch response per partition |
50
+ | `maxWaitTime` | `number` | -- | Max time (ms) broker waits for `minBytes` |
51
+ | `metadataMaxAge` | `number` | `300000` | Metadata cache TTL (ms) |
52
+ | `groupProtocol` | `'classic' \| 'consumer'` | `'classic'` | Consumer group protocol. `'consumer'` = KIP-848 (Kafka 3.7+) |
53
+ | `groupInstanceId` | `string` | -- | Static group membership ID -- prevents rebalance on restart |
54
+ | `shutdownTimeout` | `number` | `30000` | Graceful shutdown timeout in ms |
55
+ | `registry` | `SchemaRegistry` | -- | Schema registry for auto deser |
56
+
57
+ ### Lifecycle Callbacks
58
+
59
+ | Option | Type | Description |
60
+ |--------|------|-------------|
61
+ | `onBrokerConnect` | `TKafkaBrokerEventCallback` | Called when broker connects |
62
+ | `onBrokerDisconnect` | `TKafkaBrokerEventCallback` | Called when broker disconnects |
63
+
64
+ ### Message Callbacks
65
+
66
+ | Option | Type | Description |
67
+ |--------|------|-------------|
68
+ | `onMessage` | `TKafkaMessageCallback<K,V,HK,HV>` | Called for each message. Receives `{ message }` |
69
+ | `onMessageDone` | `TKafkaMessageDoneCallback<K,V,HK,HV>` | Called after `onMessage` succeeds. Receives `{ message }` |
70
+ | `onMessageError` | `TKafkaMessageErrorCallback<K,V,HK,HV>` | Called on processing error. Receives `{ error, message? }` |
71
+
72
+ ### Consumer Group Callbacks
73
+
74
+ | Option | Type | Description |
75
+ |--------|------|-------------|
76
+ | `onGroupJoin` | `TKafkaGroupJoinCallback` | Receives `{ groupId, memberId, generationId? }` |
77
+ | `onGroupLeave` | `TKafkaGroupLeaveCallback` | Receives `{ groupId, memberId }` |
78
+ | `onGroupRebalance` | `TKafkaGroupRebalanceCallback` | Receives `{ groupId }` |
79
+ | `onHeartbeatError` | `TKafkaHeartbeatErrorCallback` | Receives `{ error, groupId?, memberId? }` |
80
+
81
+ ### Lag Monitoring Callbacks
82
+
83
+ | Option | Type | Description |
84
+ |--------|------|-------------|
85
+ | `onLag` | `TKafkaLagCallback` | Receives `{ lag }` (Offsets map) |
86
+ | `onLagError` | `TKafkaLagErrorCallback` | Receives `{ error }` |
87
+
88
+ Plus all [Connection Options](./#connection-options).
89
+
90
+ ## Basic Example
91
+
92
+ ```typescript
93
+ import { KafkaConsumerHelper } from '@venizia/ignis-helpers/kafka';
94
+ import { stringDeserializers } from '@platformatic/kafka';
95
+
96
+ const helper = KafkaConsumerHelper.newInstance({
97
+ bootstrapBrokers: ['localhost:9092'],
98
+ clientId: 'order-consumer',
99
+ groupId: 'order-processing',
100
+ deserializers: stringDeserializers,
101
+
102
+ // Message lifecycle
103
+ onMessage: async ({ message }) => {
104
+ console.log(`${message.topic}[${message.partition}] @${message.offset}: ${message.key} -> ${message.value}`);
105
+ await message.commit();
106
+ },
107
+ onMessageDone: ({ message }) => {
108
+ console.log(`Done processing: ${message.key}`);
109
+ },
110
+ onMessageError: ({ error, message }) => {
111
+ console.error('Processing failed:', error.message, message?.key);
112
+ },
113
+
114
+ // Consumer group events
115
+ onGroupJoin: ({ groupId, memberId }) => console.log(`Joined ${groupId} as ${memberId}`),
116
+ onGroupLeave: ({ groupId }) => console.log(`Left ${groupId}`),
117
+ onGroupRebalance: ({ groupId }) => console.log(`Rebalance in ${groupId}`),
118
+ onHeartbeatError: ({ error }) => console.error('Heartbeat failed:', error),
119
+
120
+ // Broker events
121
+ onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}:${broker.port}`),
122
+ onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
123
+
124
+ // Lag monitoring
125
+ onLag: ({ lag }) => {
126
+ for (const [topic, partitionLags] of lag) {
127
+ partitionLags.forEach((lagValue, partition) => {
128
+ if (lagValue > 1000n) {
129
+ console.warn(`High lag on ${topic}[${partition}]: ${lagValue}`);
130
+ }
131
+ });
132
+ }
133
+ },
134
+ onLagError: ({ error }) => console.error('Lag monitoring error:', error),
135
+ });
136
+
137
+ // Start consuming
138
+ await helper.start({ topics: ['orders'] });
139
+
140
+ // Start lag monitoring (optional)
141
+ helper.startLagMonitoring({ topics: ['orders'], interval: 10_000 });
142
+
143
+ // Health check
144
+ helper.isHealthy(); // true when broker connected
145
+ helper.isReady(); // true when broker connected AND consumer is active
146
+
147
+ // Shutdown
148
+ await helper.close();
149
+ ```
150
+
151
+ ## Message Callback Flow
152
+
153
+ When `start()` is called, the helper creates a `MessagesStream` and wires the callbacks:
154
+
155
+ ```
156
+ Stream 'data' event
157
+ -> onMessage({ message })
158
+ +-- success -> onMessageDone({ message })
159
+ +-- error -> onMessageError({ error, message })
160
+
161
+ Stream 'error' event
162
+ -> onMessageError({ error }) (no message available)
163
+ ```
164
+
165
+ - `onMessage` is the main processing callback -- do your business logic here
166
+ - `onMessageDone` fires only after `onMessage` resolves successfully -- use for logging, metrics, etc.
167
+ - `onMessageError` fires if `onMessage` throws -- use for error tracking. Note that errors from `onMessageDone` also trigger `onMessageError`
168
+ - The stream `'error'` event also calls `onMessageError` (without `message` since it's a stream-level error), but only if `onMessageError` was provided
169
+
170
+ ## start()
171
+
172
+ `start()` creates the consume stream and wires all message callbacks. It must be called explicitly after construction.
173
+
174
+ ```typescript
175
+ interface IKafkaConsumeStartOptions {
176
+ topics: string[];
177
+ mode?: MessagesStreamModeValue; // Default: 'committed'
178
+ fallbackMode?: MessagesStreamFallbackModeValue; // Default: 'latest'
179
+ }
180
+ ```
181
+
182
+ | Mode | Description |
183
+ |------|-------------|
184
+ | `'committed'` | Resume from last committed offset. **Recommended for production** |
185
+ | `'latest'` | Start from the latest offset (skip existing messages) |
186
+ | `'earliest'` | Start from the beginning of the topic |
187
+ | `'manual'` | Start from explicitly provided offsets |
188
+
189
+ | Fallback | Description |
190
+ |----------|-------------|
191
+ | `'latest'` | Start from latest (default) -- ignore historical messages |
192
+ | `'earliest'` | Start from beginning -- process all historical messages |
193
+ | `'fail'` | Throw an error |
194
+
195
+ ```typescript
196
+ // Production pattern
197
+ await helper.start({ topics: ['orders'] });
198
+
199
+ // Replay all historical messages
200
+ await helper.start({ topics: ['orders'], mode: 'earliest' });
201
+
202
+ // Custom mode
203
+ await helper.start({
204
+ topics: ['orders'],
205
+ mode: 'committed',
206
+ fallbackMode: 'earliest',
207
+ });
208
+ ```
209
+
210
+ Guards against duplicate starts -- calling `start()` twice logs a warning and returns immediately.
211
+
212
+ ## Lag Monitoring
213
+
214
+ ```typescript
215
+ // Start monitoring (polls every interval)
216
+ helper.startLagMonitoring({ topics: ['orders'], interval: 10_000 });
217
+
218
+ // Stop monitoring
219
+ helper.stopLagMonitoring();
220
+ ```
221
+
222
+ Lag data is delivered via the `onLag` callback. Errors via `onLagError`.
223
+
224
+ Guards against duplicate starts -- calling `startLagMonitoring()` twice logs a warning.
225
+
226
+ For one-time lag checks, use the underlying consumer directly:
227
+
228
+ ```typescript
229
+ const lag = await helper.getConsumer().getLag({ topics: ['orders'] });
230
+ ```
231
+
232
+ ## Graceful Shutdown
233
+
234
+ `close()` implements an ordered shutdown:
235
+
236
+ 1. Stop lag monitoring
237
+ 2. Close the stream (calls `stream.close()` callback-style)
238
+ 3. Close the consumer client (calls `client.close(true)` with graceful timeout, or force)
239
+ 4. Set health status to `'disconnected'`
240
+
241
+ ```typescript
242
+ // Graceful (recommended)
243
+ await helper.close();
244
+
245
+ // Force
246
+ await helper.close({ isForce: true });
247
+ ```
248
+
249
+ ## Direct Stream Access
250
+
251
+ If you don't use the callback pattern, you can access the stream directly after `start()`:
252
+
253
+ ```typescript
254
+ // After start()
255
+ const stream = helper.getStream();
256
+
257
+ // Or use the consumer directly (bypass helper's start())
258
+ const consumer = helper.getConsumer();
259
+ const stream = await consumer.consume({
260
+ topics: ['orders'],
261
+ mode: 'committed',
262
+ fallbackMode: 'latest',
263
+ });
264
+
265
+ for await (const message of stream) {
266
+ await processMessage(message);
267
+ await message.commit();
268
+ }
269
+ ```
270
+
271
+ ## API Reference (`@platformatic/kafka`)
272
+
273
+ ### Message Object
274
+
275
+ ```typescript
276
+ interface Message<Key, Value, HeaderKey, HeaderValue> {
277
+ topic: string;
278
+ key: Key;
279
+ value: Value;
280
+ partition: number;
281
+ offset: bigint;
282
+ timestamp: bigint;
283
+ headers: Map<HeaderKey, HeaderValue>;
284
+ metadata: Record<string, unknown>;
285
+ commit(callback?: (error?: Error) => void): void | Promise<void>;
286
+ toJSON(): MessageJSON<Key, Value, HeaderKey, HeaderValue>;
287
+ }
288
+ ```
289
+
290
+ > [!WARNING]
291
+ > `message.offset` and `message.timestamp` are `bigint`. When using `JSON.stringify`, provide a custom replacer:
292
+ > ```typescript
293
+ > JSON.stringify(data, (_key, value) => (typeof value === 'bigint' ? value.toString() : value))
294
+ > ```
295
+
296
+ ### MessagesStream
297
+
298
+ `MessagesStream` extends Node.js `Readable`. Three consumption patterns:
299
+
300
+ **Async Iterator** (sequential, backpressure):
301
+ ```typescript
302
+ for await (const message of stream) {
303
+ await processMessage(message);
304
+ await message.commit();
305
+ }
306
+ ```
307
+
308
+ **Event-Based** (high-throughput):
309
+ ```typescript
310
+ stream.on('data', (message) => {
311
+ processMessage(message);
312
+ message.commit();
313
+ });
314
+ ```
315
+
316
+ **Pause/Resume** (manual flow control):
317
+ ```typescript
318
+ stream.on('data', async (message) => {
319
+ stream.pause();
320
+ await heavyProcessing(message);
321
+ message.commit();
322
+ stream.resume();
323
+ });
324
+ ```
325
+
326
+ ### Offset Management
327
+
328
+ ```typescript
329
+ // Manual commit (when autocommit: false)
330
+ for await (const message of stream) {
331
+ await processMessage(message);
332
+ await message.commit();
333
+ }
334
+
335
+ // Bulk commit
336
+ await consumer.commit({
337
+ offsets: [
338
+ { topic: 'orders', partition: 0, offset: 150n, leaderEpoch: 0 },
339
+ { topic: 'orders', partition: 1, offset: 300n, leaderEpoch: 0 },
340
+ ],
341
+ });
342
+
343
+ // List offsets
344
+ const offsets = await consumer.listOffsets({ topics: ['orders'] });
345
+ const committed = await consumer.listCommittedOffsets({
346
+ topics: [{ topic: 'orders', partitions: [0, 1, 2] }],
347
+ });
348
+ ```
349
+
350
+ ### Consumer Group Management
351
+
352
+ ```typescript
353
+ consumer.groupId; // string
354
+ consumer.memberId; // string | null
355
+ consumer.generationId; // number
356
+ consumer.assignments; // GroupAssignment[] | null
357
+ consumer.isActive(); // boolean
358
+
359
+ // Static membership -- prevents rebalance on restart
360
+ const helper = KafkaConsumerHelper.newInstance({
361
+ ...
362
+ groupInstanceId: 'worker-1',
363
+ sessionTimeout: 60_000,
364
+ });
365
+ ```
366
+
367
+ ### Consumer Group Partitioning
368
+
369
+ When multiple consumers share the same `groupId`, Kafka distributes topic partitions across group members:
370
+
371
+ ```
372
+ Topic "orders" (3 partitions)
373
+ +-- Partition 0 -> Consumer A
374
+ +-- Partition 1 -> Consumer B
375
+ +-- Partition 2 -> Consumer C
376
+ ```
377
+
378
+ - Each partition is assigned to **exactly one** consumer in the group
379
+ - If a consumer leaves/crashes, its partitions are redistributed (**rebalance**)
380
+ - If consumers > partitions, excess consumers sit idle
381
+ - Messages within a partition are processed **in order**
382
+
383
+ > [!TIP]
384
+ > Create topics with enough partitions for your expected parallelism. You can increase partitions later with `admin.createPartitions()`, but you cannot decrease them.