@venizia/ignis-docs 0.2.0 → 0.2.1-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +24 -13
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +27 -3
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +8 -4
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +247 -153
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +109 -323
- package/content/extensions/components/authentication/api.md +489 -602
- package/content/extensions/components/authentication/errors.md +135 -498
- package/content/extensions/components/authentication/index.md +89 -801
- package/content/extensions/components/authentication/usage.md +231 -955
- package/content/extensions/components/authorization/api.md +991 -644
- package/content/extensions/components/authorization/errors.md +204 -208
- package/content/extensions/components/authorization/getting-started.md +227 -0
- package/content/extensions/components/authorization/index.md +88 -795
- package/content/extensions/components/authorization/usage.md +219 -528
- package/content/extensions/components/health-check.md +77 -243
- package/content/extensions/components/index.md +24 -90
- package/content/extensions/components/mail/api.md +553 -285
- package/content/extensions/components/mail/errors.md +76 -62
- package/content/extensions/components/mail/index.md +111 -463
- package/content/extensions/components/mail/usage.md +139 -173
- package/content/extensions/components/request-tracker.md +70 -173
- package/content/extensions/components/socket-io/api.md +462 -785
- package/content/extensions/components/socket-io/errors.md +49 -51
- package/content/extensions/components/socket-io/index.md +69 -372
- package/content/extensions/components/socket-io/usage.md +212 -105
- package/content/extensions/components/static-asset/api.md +461 -141
- package/content/extensions/components/static-asset/errors.md +121 -53
- package/content/extensions/components/static-asset/index.md +84 -606
- package/content/extensions/components/static-asset/usage.md +184 -299
- package/content/extensions/components/template/index.md +3 -3
- package/content/extensions/components/websocket/api.md +311 -404
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +75 -407
- package/content/extensions/components/websocket/usage.md +120 -338
- package/content/extensions/helpers/cron/index.md +52 -160
- package/content/extensions/helpers/crypto/index.md +67 -480
- package/content/extensions/helpers/crypto/reference.md +528 -0
- package/content/extensions/helpers/env/index.md +64 -178
- package/content/extensions/helpers/error/index.md +286 -196
- package/content/extensions/helpers/index.md +61 -47
- package/content/extensions/helpers/inversion/index.md +76 -550
- package/content/extensions/helpers/inversion/reference.md +530 -0
- package/content/extensions/helpers/kafka/admin.md +23 -3
- package/content/extensions/helpers/kafka/compile-binary.md +83 -52
- package/content/extensions/helpers/kafka/consumer.md +65 -28
- package/content/extensions/helpers/kafka/examples.md +46 -253
- package/content/extensions/helpers/kafka/index.md +55 -617
- package/content/extensions/helpers/kafka/producer.md +156 -22
- package/content/extensions/helpers/kafka/schema-registry.md +59 -79
- package/content/extensions/helpers/logger/hf-logger.md +220 -0
- package/content/extensions/helpers/logger/index.md +78 -552
- package/content/extensions/helpers/logger/pino.md +105 -0
- package/content/extensions/helpers/logger/reference.md +937 -0
- package/content/extensions/helpers/network/api.md +276 -195
- package/content/extensions/helpers/network/index.md +87 -524
- package/content/extensions/helpers/queue/index.md +80 -897
- package/content/extensions/helpers/queue/reference.md +494 -0
- package/content/extensions/helpers/redis/index.md +86 -640
- package/content/extensions/helpers/redis/reference.md +784 -0
- package/content/extensions/helpers/secrets/index.md +136 -0
- package/content/extensions/helpers/socket-io/api.md +325 -204
- package/content/extensions/helpers/socket-io/index.md +79 -429
- package/content/extensions/helpers/storage/api.md +584 -464
- package/content/extensions/helpers/storage/index.md +80 -573
- package/content/extensions/helpers/types/index.md +75 -495
- package/content/extensions/helpers/types/reference.md +689 -0
- package/content/extensions/helpers/uid/index.md +176 -189
- package/content/extensions/helpers/websocket/api.md +366 -214
- package/content/extensions/helpers/websocket/index.md +68 -503
- package/content/extensions/helpers/worker-thread/index.md +62 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/extensions/index.md +38 -39
- package/content/extensions/src-details/mcp-server.md +96 -548
- package/content/guides/core-concepts/persistent/datasources.md +2 -2
- package/content/guides/core-concepts/persistent/index.md +5 -1
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/pglite.md +218 -0
- package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
- package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
- package/content/guides/core-concepts/persistent/search-typesense.md +28 -16
- package/content/guides/core-concepts/persistent/sqlite.md +296 -0
- package/content/guides/core-concepts/persistent/transactions.md +12 -11
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/get-started/5-minute-quickstart.md +59 -206
- package/content/guides/get-started/philosophy.md +135 -670
- package/content/guides/get-started/setup.md +53 -74
- package/content/guides/migrations/redis-helpers-migration.md +5 -4
- package/content/guides/migrations/scoped-rbac-migration.md +5 -5
- package/content/guides/migrations/unified-connectors-migration.md +8 -7
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/guides/tutorials/realtime-chat.md +1 -1
- package/content/references/base/application.md +64 -22
- package/content/references/base/components.md +3 -3
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/controllers.md +12 -12
- package/content/references/base/datasources-reference.md +600 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +25 -46
- package/content/references/base/filter-system/application-usage.md +95 -123
- package/content/references/base/filter-system/array-operators.md +33 -43
- package/content/references/base/filter-system/comparison-operators.md +55 -63
- package/content/references/base/filter-system/default-filter.md +144 -350
- package/content/references/base/filter-system/fields-order-pagination.md +116 -148
- package/content/references/base/filter-system/index.md +114 -253
- package/content/references/base/filter-system/json-filtering.md +52 -181
- package/content/references/base/filter-system/list-operators.md +28 -44
- package/content/references/base/filter-system/logical-operators.md +69 -114
- package/content/references/base/filter-system/null-operators.md +41 -98
- package/content/references/base/filter-system/pattern-matching.md +48 -51
- package/content/references/base/filter-system/quick-reference.md +93 -196
- package/content/references/base/filter-system/range-operators.md +22 -38
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +173 -232
- package/content/references/base/grpc-controllers.md +53 -17
- package/content/references/base/index.md +5 -3
- package/content/references/base/middlewares.md +43 -28
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +81 -1452
- package/content/references/base/providers.md +8 -8
- package/content/references/base/repositories/advanced.md +281 -419
- package/content/references/base/repositories/index.md +84 -644
- package/content/references/base/repositories/mixins.md +25 -21
- package/content/references/base/repositories/relations.md +194 -375
- package/content/references/base/repositories/soft-deletable.md +67 -55
- package/content/references/base/secrets.md +267 -0
- package/content/references/base/services.md +8 -6
- package/content/references/configuration/environment-variables.md +73 -21
- package/content/references/configuration/index.md +51 -31
- package/content/references/index.md +1 -1
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/duration.md +85 -0
- package/content/references/utilities/index.md +6 -2
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +81 -61
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +58 -218
- package/content/references/utilities/retry.md +139 -0
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/dist/mcp-server/index.js +0 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
- package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
- package/package.json +24 -23
|
@@ -1,45 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
```
|
|
7
|
-
ENOENT: no such file or directory, open '/$bunfs/dist/native.wasm'
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
The failure happens while the module graph is still loading -- before the IGNIS application boots, so
|
|
11
|
-
no log line, no lifecycle hook, and no error handler of yours ever runs.
|
|
1
|
+
---
|
|
2
|
+
title: Kafka - Compiling to a Single Binary
|
|
3
|
+
description: The platformaticKafkaPlugins() Bun bundler plugins required when compiling an app that imports a Kafka helper
|
|
4
|
+
difficulty: advanced
|
|
5
|
+
---
|
|
12
6
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
`@platformatic/kafka` computes Kafka's CRC32C checksums and lz4/snappy compression in WebAssembly,
|
|
16
|
-
through `@platformatic/wasm-utils`. The default entrypoint of that package reads the wasm payload
|
|
17
|
-
from disk at module load time:
|
|
18
|
-
|
|
19
|
-
```javascript
|
|
20
|
-
// @platformatic/wasm-utils/dist/index.js
|
|
21
|
-
const wasm = readFileSync(new URL('../dist/native.wasm', import.meta.url));
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
`bun build --compile` embeds JavaScript modules only -- assets such as `native.wasm` are not carried
|
|
25
|
-
into the executable. Inside the binary, `import.meta.url` resolves against the virtual `/$bunfs`
|
|
26
|
-
filesystem, the file is not there, and the read throws.
|
|
27
|
-
|
|
28
|
-
Running from source (`bun run`, `bun .`) is unaffected: `node_modules` is on disk, so the read
|
|
29
|
-
succeeds. The bug only exists in compiled binaries.
|
|
30
|
-
|
|
31
|
-
## The fix
|
|
32
|
-
|
|
33
|
-
`@platformatic/wasm-utils` ships a second entrypoint, `@platformatic/wasm-utils/bundled`, exposing
|
|
34
|
-
the same API with the wasm payload inlined as base64 -- no filesystem read. `platformaticWasmPlugin`
|
|
35
|
-
swaps one entrypoint for the other at bundle time.
|
|
7
|
+
# Compiling to a Single Binary
|
|
36
8
|
|
|
37
|
-
|
|
38
|
-
plugins:
|
|
9
|
+
`platformaticKafkaPlugins()` returns every Bun bundler plugin `@platformatic/kafka` needs to survive `bun build --compile`. Register them whenever you compile an application that imports a Kafka helper. Skip them, and the binary crashes on its first run.
|
|
39
10
|
|
|
40
11
|
```typescript
|
|
41
12
|
// scripts/compile.ts
|
|
42
|
-
import {
|
|
13
|
+
import { platformaticKafkaPlugins } from '@venizia/ignis-helpers/kafka';
|
|
43
14
|
|
|
44
15
|
const built = await Bun.build({
|
|
45
16
|
entrypoints: ['./dist/index.js'],
|
|
@@ -50,7 +21,7 @@ const built = await Bun.build({
|
|
|
50
21
|
target: process.env.BUN_TARGET ?? 'bun-linux-x64',
|
|
51
22
|
outfile: './dist/bin',
|
|
52
23
|
},
|
|
53
|
-
plugins:
|
|
24
|
+
plugins: platformaticKafkaPlugins(),
|
|
54
25
|
});
|
|
55
26
|
|
|
56
27
|
if (!built.success) {
|
|
@@ -59,6 +30,8 @@ if (!built.success) {
|
|
|
59
30
|
}
|
|
60
31
|
```
|
|
61
32
|
|
|
33
|
+
`bun build --compile` on the command line cannot register plugins. Compile through a build script instead:
|
|
34
|
+
|
|
62
35
|
```json
|
|
63
36
|
{
|
|
64
37
|
"scripts": {
|
|
@@ -67,26 +40,84 @@ if (!built.success) {
|
|
|
67
40
|
}
|
|
68
41
|
```
|
|
69
42
|
|
|
70
|
-
The
|
|
71
|
-
it works with hoisted and isolated `node_modules` layouts alike, and pins no package version.
|
|
43
|
+
## The two crashes
|
|
72
44
|
|
|
73
|
-
|
|
45
|
+
| Crash | Plugin that prevents it |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `ENOENT: no such file or directory, open '/$bunfs/dist/native.wasm'` | `platformaticWasmPlugin()` |
|
|
48
|
+
| `Cannot find package 'ajv-draft-04' from '/$bunfs/root/index.js'` | `platformaticRequirePlugin()` |
|
|
49
|
+
|
|
50
|
+
Both fire while the module graph is still loading, before the IGNIS application boots. No log line, no lifecycle hook, and no error handler of yours ever runs.
|
|
51
|
+
|
|
52
|
+
Running from source is unaffected. `bun run` and `bun .` keep `node_modules` on disk, so both reads succeed. The crashes exist only in compiled binaries.
|
|
74
53
|
|
|
75
|
-
|
|
54
|
+
## Why the wasm read fails
|
|
55
|
+
|
|
56
|
+
`@platformatic/kafka` computes Kafka's CRC32C checksums and lz4/snappy compression in WebAssembly, through `@platformatic/wasm-utils`. That package reads its payload from disk at module load:
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
// @platformatic/wasm-utils/dist/index.js
|
|
60
|
+
const wasm = readFileSync(new URL('../dist/native.wasm', import.meta.url));
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`bun build --compile` embeds JavaScript modules only. Assets such as `native.wasm` never reach the executable, so `import.meta.url` resolves against the virtual `/$bunfs` filesystem and the read throws.
|
|
64
|
+
|
|
65
|
+
`platformaticWasmPlugin()` redirects the import to `@platformatic/wasm-utils/bundled`, the same API with the payload inlined as base64.
|
|
66
|
+
|
|
67
|
+
## Why the package lookup fails
|
|
68
|
+
|
|
69
|
+
Since 2.8.0, `@platformatic/kafka` resolves two dependencies at module scope through `createRequire`:
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
// @platformatic/kafka/dist/registries/confluent-schema-registry.js
|
|
73
|
+
const require = createRequire(import.meta.url);
|
|
74
|
+
const AjvDraft04 = require('ajv-draft-04');
|
|
75
|
+
const draft06MetaSchema = require('ajv/dist/refs/json-schema-draft-06.json');
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Three facts make that fatal in a binary:
|
|
79
|
+
|
|
80
|
+
- **The bundler cannot see through `createRequire`.** Neither module is embedded, and the bare specifier survives verbatim into the binary.
|
|
81
|
+
- **The module always loads.** `dist/index.js` re-exports the schema registry, so importing anything from the package runs those two lines. A schema registry you never use still crashes the binary.
|
|
82
|
+
- **A compiled binary has no `node_modules`.** `import.meta.url` resolves against `/$bunfs` and the lookup fails.
|
|
83
|
+
|
|
84
|
+
`platformaticRequirePlugin()` rewrites each module-scope `require()` into a static import at bundle time, so the bundler pulls the module into the binary.
|
|
85
|
+
|
|
86
|
+
> [!WARNING]
|
|
87
|
+
> Installing `ajv-draft-04` as a direct dependency does not fix this. The defect is the resolution mechanism, not a missing package, so the second line fails identically.
|
|
88
|
+
|
|
89
|
+
## Verifying
|
|
76
90
|
|
|
77
91
|
```bash
|
|
78
|
-
|
|
79
|
-
./dist/bin
|
|
92
|
+
./dist/bin # boots instead of crashing
|
|
93
|
+
grep -ac 'native.wasm' ./dist/bin # 0 - the wasm payload is inlined
|
|
94
|
+
grep -ac 'ajv-draft-04' ./dist/bin # 0 - the package is bundled in
|
|
80
95
|
```
|
|
81
96
|
|
|
82
|
-
The
|
|
97
|
+
The last count is meaningful only for a minified build. An unminified bundle keeps package paths in module comments.
|
|
98
|
+
|
|
99
|
+
The binary grows by roughly 76 KB for the base64 wasm module, plus the size of the two hoisted packages.
|
|
83
100
|
|
|
84
101
|
## Notes
|
|
85
102
|
|
|
86
|
-
-
|
|
87
|
-
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
|
|
103
|
+
- **Register the pair, not the individual plugins.** `platformaticKafkaPlugins()` picks up any future addition without another edit to your compile script. `platformaticWasmPlugin()` and `platformaticRequirePlugin()` stay exported for a build that needs one alone.
|
|
104
|
+
- **Upgrading `@platformatic/kafka` does not remove the need for the plugins.** Every release to date imports the default `@platformatic/wasm-utils` entrypoint, and 2.8.0 introduced the `createRequire` calls in a minor release.
|
|
105
|
+
- **An unresolvable specifier now fails the build**, with Bun's own resolution error and `built.success === false`. That is the point of hoisting to a static import: you learn at build time instead of on the first run in production.
|
|
106
|
+
- **Both plugins resolve relative to the importing module's own directory.** That works with hoisted and isolated `node_modules` layouts alike, and pins no package version.
|
|
107
|
+
- **Apps that never import a Kafka helper need no plugins.** Nothing pulls in `@platformatic/wasm-utils` or the schema registry, and neither plugin ever fires.
|
|
108
|
+
- **`platformaticRequirePlugin()` skips `protobufjs` and `@node-rs/crc32`.** Both are optional peers of `@platformatic/kafka`, and a static import would break builds that do not install them.
|
|
109
|
+
- **Patching `node_modules` during the build achieves the same result, but at a cost.** It mutates a dependency in place, pins the store path to one version, and leaves the tree dirty when a build fails. The plugins need none of that.
|
|
110
|
+
|
|
111
|
+
## See also
|
|
112
|
+
|
|
113
|
+
- [Kafka Overview](./) - the four helpers these plugins protect
|
|
114
|
+
- [Producer](./producer) / [Consumer](./consumer) / [Admin](./admin) - any of these importing into a compiled binary triggers this caveat
|
|
115
|
+
- [Schema Registry](./schema-registry) - the helper that wraps the module the second crash comes from
|
|
116
|
+
- [Examples & Troubleshooting](./examples) - other Kafka connection and configuration errors
|
|
117
|
+
|
|
118
|
+
**Files:**
|
|
119
|
+
|
|
120
|
+
- [`packages/helpers/src/modules/queue/kafka/bundler/plugins.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/bundler/plugins.ts) - `platformaticKafkaPlugins`
|
|
121
|
+
- [`packages/helpers/src/modules/queue/kafka/bundler/platformatic-wasm.plugin.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/bundler/platformatic-wasm.plugin.ts) - `platformaticWasmPlugin`
|
|
122
|
+
- [`packages/helpers/src/modules/queue/kafka/bundler/platformatic-require.plugin.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/bundler/platformatic-require.plugin.ts) - `platformaticRequirePlugin`
|
|
123
|
+
- [`packages/helpers/src/modules/queue/kafka/bundler/common/constants.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/bundler/common/constants.ts) - `KafkaBundlerPluginNames`, `PlatformaticWasmSpecifiers`, `PlatformaticRequireSpecifiers`
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Kafka Consumer
|
|
3
|
+
description: KafkaConsumerHelper - message callbacks, automatic reconnect, and lag monitoring
|
|
4
|
+
difficulty: intermediate
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# Consumer
|
|
2
8
|
|
|
3
|
-
The `KafkaConsumerHelper` wraps `@platformatic/kafka`'s `Consumer` with health tracking, graceful shutdown, message callbacks,
|
|
9
|
+
The `KafkaConsumerHelper` wraps `@platformatic/kafka`'s `Consumer` with health tracking, graceful shutdown, message callbacks, group callbacks, automatic reconnect, and lag monitoring.
|
|
4
10
|
|
|
5
11
|
```typescript
|
|
6
12
|
class KafkaConsumerHelper<
|
|
@@ -18,7 +24,7 @@ class KafkaConsumerHelper<
|
|
|
18
24
|
| `newInstance(opts)` | `static newInstance<K,V,HK,HV>(opts): KafkaConsumerHelper<K,V,HK,HV>` | Factory method |
|
|
19
25
|
| `getConsumer()` | `(): Consumer<K,V,HK,HV>` | Access the underlying `Consumer` |
|
|
20
26
|
| `getStream()` | `(): MessagesStream \| null` | Get the active stream (after `start()`) |
|
|
21
|
-
| `start(opts)` | `(opts: IKafkaConsumeStartOptions): Promise<void>` | Start consuming (creates stream, wires callbacks) |
|
|
27
|
+
| `start(opts)` | `(opts: IKafkaConsumeStartOptions): Promise<void>` | Start consuming (creates stream, wires callbacks, drives automatic reconnect) |
|
|
22
28
|
| `startLagMonitoring(opts)` | `(opts: { topics: string[]; interval?: number }): void` | Start periodic lag monitoring |
|
|
23
29
|
| `stopLagMonitoring()` | `(): void` | Stop lag monitoring |
|
|
24
30
|
| `isHealthy()` | `(): boolean` | `true` when at least one broker connected |
|
|
@@ -34,26 +40,28 @@ interface IKafkaConsumerOptions<KeyType, ValueType, HeaderKeyType, HeaderValueTy
|
|
|
34
40
|
extends IKafkaConnectionOptions
|
|
35
41
|
```
|
|
36
42
|
|
|
43
|
+
Plus the shared [Connection & Authentication](./producer#connection--authentication) options (`bootstrapBrokers`, `clientId`, `retries`, `sasl`, `tls`, ...), documented once on the Producer page.
|
|
44
|
+
|
|
37
45
|
### Consumer Configuration
|
|
38
46
|
|
|
39
47
|
| Option | Type | Default | Description |
|
|
40
48
|
|--------|------|---------|-------------|
|
|
41
|
-
| `groupId` | `string` |
|
|
49
|
+
| `groupId` | `string` | - | Consumer group ID. **Required** |
|
|
42
50
|
| `identifier` | `string` | `'kafka-consumer'` | Scoped logging identifier |
|
|
43
|
-
| `deserializers` | `Partial<Deserializers<K,V,HK,HV>>` |
|
|
51
|
+
| `deserializers` | `Partial<Deserializers<K,V,HK,HV>>` | - | Key/value/header deserializers |
|
|
44
52
|
| `autocommit` | `boolean \| number` | `false` | Auto-commit offsets. `true` = default interval, `number` = custom ms |
|
|
45
|
-
| `sessionTimeout` | `number` | `60000` | Session timeout
|
|
46
|
-
| `heartbeatInterval` | `number` | `10000` | Heartbeat interval
|
|
53
|
+
| `sessionTimeout` | `number` | `60000` | Session timeout - consumer removed from group if no heartbeat |
|
|
54
|
+
| `heartbeatInterval` | `number` | `10000` | Heartbeat interval - must be less than `sessionTimeout` |
|
|
47
55
|
| `rebalanceTimeout` | `number` | `sessionTimeout` | Max time for rebalance. Defaults to the value of `sessionTimeout` |
|
|
48
56
|
| `highWaterMark` | `number` | `1024` | Stream buffer size (messages) |
|
|
49
57
|
| `minBytes` | `number` | `1` | Min bytes per fetch response |
|
|
50
|
-
| `maxBytes` | `number` |
|
|
51
|
-
| `maxWaitTime` | `number` |
|
|
58
|
+
| `maxBytes` | `number` | `10485760` (10 MB) | Max bytes per fetch response per partition |
|
|
59
|
+
| `maxWaitTime` | `number` | `5000` | Max time (ms) broker waits for `minBytes` |
|
|
52
60
|
| `metadataMaxAge` | `number` | `300000` | Metadata cache TTL (ms) |
|
|
53
61
|
| `groupProtocol` | `'classic' \| 'consumer'` | `'classic'` | Consumer group protocol. `'consumer'` = KIP-848 (Kafka 3.7+) |
|
|
54
|
-
| `groupInstanceId` | `string` |
|
|
62
|
+
| `groupInstanceId` | `string` | - | Static group membership ID - prevents rebalance on restart |
|
|
55
63
|
| `shutdownTimeout` | `number` | `30000` | Graceful shutdown timeout in ms |
|
|
56
|
-
| `registry` | `SchemaRegistry` |
|
|
64
|
+
| `registry` | `SchemaRegistry` | - | Schema registry for auto deser |
|
|
57
65
|
|
|
58
66
|
### Lifecycle Callbacks
|
|
59
67
|
|
|
@@ -86,8 +94,6 @@ interface IKafkaConsumerOptions<KeyType, ValueType, HeaderKeyType, HeaderValueTy
|
|
|
86
94
|
| `onLag` | `TKafkaLagCallback` | Receives `{ lag }` (Offsets map) |
|
|
87
95
|
| `onLagError` | `TKafkaLagErrorCallback` | Receives `{ error }` |
|
|
88
96
|
|
|
89
|
-
Plus all [Connection Options](./#connection-options).
|
|
90
|
-
|
|
91
97
|
## Basic Example
|
|
92
98
|
|
|
93
99
|
```typescript
|
|
@@ -163,36 +169,44 @@ Stream 'error' event
|
|
|
163
169
|
-> onMessageError({ error }) (no message available)
|
|
164
170
|
```
|
|
165
171
|
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
- The stream `'error'`
|
|
172
|
+
- **`onMessage` is the main processing callback.** Put your business logic here.
|
|
173
|
+
- **`onMessageDone` fires only after `onMessage` resolves successfully.** Use it for logging, metrics, and similar side effects. An error thrown from `onMessageDone` also triggers `onMessageError`.
|
|
174
|
+
- **`onMessageError` fires if `onMessage` throws.** It also fires for the stream's own `'error'` event. That case carries no `message` - it's a stream-level error, not a per-message one.
|
|
175
|
+
- **The stream `'error'` listener is always attached**, whether or not you pass `onMessageError`. An `EventEmitter` `'error'` event with zero listeners becomes an uncaught exception.
|
|
176
|
+
- **Pull-style consumers benefit too.** Without this listener, a consumer using `start()` + `getStream()` with no `onMessage` would take down the whole process on the first broker drop.
|
|
170
177
|
|
|
171
178
|
## start()
|
|
172
179
|
|
|
173
|
-
`start()` creates the consume stream and wires all message callbacks.
|
|
180
|
+
`start()` creates the consume stream and wires all message callbacks. Call it explicitly after construction - the constructor never calls it for you. It also guards against duplicate starts: calling it twice logs a warning and returns immediately.
|
|
174
181
|
|
|
175
182
|
```typescript
|
|
176
183
|
interface IKafkaConsumeStartOptions {
|
|
177
184
|
topics: string[];
|
|
178
|
-
mode?: MessagesStreamModeValue;
|
|
179
|
-
fallbackMode?: MessagesStreamFallbackModeValue;
|
|
185
|
+
mode?: MessagesStreamModeValue;
|
|
186
|
+
fallbackMode?: MessagesStreamFallbackModeValue;
|
|
187
|
+
reconnectDelayMs?: number;
|
|
188
|
+
maxReconnectAttempts?: number;
|
|
180
189
|
}
|
|
181
190
|
```
|
|
182
191
|
|
|
183
192
|
| Mode | Description |
|
|
184
193
|
|------|-------------|
|
|
185
|
-
| `'committed'` | Resume from last committed offset. **Recommended for production** |
|
|
194
|
+
| `'committed'` (default) | Resume from last committed offset. **Recommended for production** |
|
|
186
195
|
| `'latest'` | Start from the latest offset (skip existing messages) |
|
|
187
196
|
| `'earliest'` | Start from the beginning of the topic |
|
|
188
197
|
| `'manual'` | Start from explicitly provided offsets |
|
|
189
198
|
|
|
190
199
|
| Fallback | Description |
|
|
191
200
|
|----------|-------------|
|
|
192
|
-
| `'latest'` | Start from latest
|
|
193
|
-
| `'earliest'` | Start from beginning
|
|
201
|
+
| `'latest'` (default) | Start from latest - ignore historical messages |
|
|
202
|
+
| `'earliest'` | Start from beginning - process all historical messages |
|
|
194
203
|
| `'fail'` | Throw an error |
|
|
195
204
|
|
|
205
|
+
| Reconnect option | Default | Description |
|
|
206
|
+
|-------------------|---------|-------------|
|
|
207
|
+
| `reconnectDelayMs` | `2000` | Delay before each automatic reconnect attempt |
|
|
208
|
+
| `maxReconnectAttempts` | `5` | Consecutive reconnect attempts before the consume loop gives up |
|
|
209
|
+
|
|
196
210
|
```typescript
|
|
197
211
|
// Production pattern
|
|
198
212
|
await helper.start({ topics: ['orders'] });
|
|
@@ -200,15 +214,27 @@ await helper.start({ topics: ['orders'] });
|
|
|
200
214
|
// Replay all historical messages
|
|
201
215
|
await helper.start({ topics: ['orders'], mode: 'earliest' });
|
|
202
216
|
|
|
203
|
-
// Custom mode
|
|
217
|
+
// Custom mode and reconnect budget
|
|
204
218
|
await helper.start({
|
|
205
219
|
topics: ['orders'],
|
|
206
220
|
mode: 'committed',
|
|
207
221
|
fallbackMode: 'earliest',
|
|
222
|
+
reconnectDelayMs: 5_000,
|
|
223
|
+
maxReconnectAttempts: 10,
|
|
208
224
|
});
|
|
209
225
|
```
|
|
210
226
|
|
|
211
|
-
|
|
227
|
+
## Automatic reconnect
|
|
228
|
+
|
|
229
|
+
When `onMessage` is provided, `start()` drives a background consume loop on top of the stream. That loop reconnects on its own:
|
|
230
|
+
|
|
231
|
+
- **Only the callback-driven loop reconnects.** A pull-style consumer using `getStream()` or `consumer.consume()` directly owns its own retry logic. The helper's automatic reconnect runs only inside `startConsumeLoop`, which is wired exclusively when `onMessage` is set.
|
|
232
|
+
- **A full broker outage marks the session stale.** This happens when every broker disconnects - `getConnectedBrokerCount()` drops to `0` via `client:broker:disconnect` or `client:broker:failed` events.
|
|
233
|
+
- **The helper reacts immediately.** It destroys the current stream right away, instead of waiting for the stream to error out on its own.
|
|
234
|
+
- **Reconnect rebuilds the client after a stale session.** The next attempt, after `reconnectDelayMs`, constructs a brand-new `@platformatic/kafka` `Consumer` with the original options and swaps it in.
|
|
235
|
+
- **A fresh client forces a clean group rejoin**, instead of reusing session state Kafka has likely already expired. Lag monitoring re-arms automatically on the new client.
|
|
236
|
+
- **Attempts are capped.** After `maxReconnectAttempts` consecutive failures, the consume loop exits and logs an error. Message processing stops until you call `start()` again with a new set of options.
|
|
237
|
+
- **Every retry is logged**: the attempt number, the delay, and the current connected-broker count. A stuck reconnect loop stays visible in application logs without extra instrumentation.
|
|
212
238
|
|
|
213
239
|
## Lag Monitoring
|
|
214
240
|
|
|
@@ -220,9 +246,7 @@ helper.startLagMonitoring({ topics: ['orders'], interval: 10_000 });
|
|
|
220
246
|
helper.stopLagMonitoring();
|
|
221
247
|
```
|
|
222
248
|
|
|
223
|
-
Lag data
|
|
224
|
-
|
|
225
|
-
Guards against duplicate starts -- calling `startLagMonitoring()` twice logs a warning.
|
|
249
|
+
Lag data arrives through the `onLag` callback; errors through `onLagError`. `interval` defaults to `30000` ms. Calling `startLagMonitoring()` twice logs a warning instead of starting a second poll loop.
|
|
226
250
|
|
|
227
251
|
For one-time lag checks, use the underlying consumer directly:
|
|
228
252
|
|
|
@@ -357,7 +381,7 @@ consumer.generationId; // number
|
|
|
357
381
|
consumer.assignments; // GroupAssignment[] | null
|
|
358
382
|
consumer.isActive(); // boolean
|
|
359
383
|
|
|
360
|
-
// Static membership
|
|
384
|
+
// Static membership - prevents rebalance on restart
|
|
361
385
|
const helper = KafkaConsumerHelper.newInstance({
|
|
362
386
|
...
|
|
363
387
|
groupInstanceId: 'worker-1',
|
|
@@ -383,3 +407,16 @@ Topic "orders" (3 partitions)
|
|
|
383
407
|
|
|
384
408
|
> [!TIP]
|
|
385
409
|
> Create topics with enough partitions for your expected parallelism. You can increase partitions later with `admin.createPartitions()`, but you cannot decrease them.
|
|
410
|
+
|
|
411
|
+
## See also
|
|
412
|
+
|
|
413
|
+
- [Kafka Overview](./) - the four helpers, shared health/close API, and the compile-binary caveat
|
|
414
|
+
- [Producer](./producer) - the sending side, plus the shared Connection & Authentication options
|
|
415
|
+
- [Admin](./admin) - create topics and inspect consumer groups from outside the running consumer
|
|
416
|
+
- [Examples & Troubleshooting](./examples) - IoC wiring and the common connection-error lookup table
|
|
417
|
+
|
|
418
|
+
**Files:**
|
|
419
|
+
|
|
420
|
+
- [`packages/helpers/src/modules/queue/kafka/consumer.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/consumer.ts) - `KafkaConsumerHelper`, consume loop, automatic reconnect
|
|
421
|
+
- [`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`, shared health tracking and shutdown
|
|
422
|
+
- [`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) - `IKafkaConsumerOptions`, `IKafkaConsumeStartOptions`
|