@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.
Files changed (174) 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 +24 -13
  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 +27 -3
  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 +8 -4
  17. package/content/best-practices/data-modeling.md +78 -62
  18. package/content/best-practices/deployment-strategies.md +56 -19
  19. package/content/best-practices/error-handling.md +247 -153
  20. package/content/best-practices/index.md +6 -0
  21. package/content/best-practices/performance-optimization.md +26 -13
  22. package/content/best-practices/security-guidelines.md +35 -9
  23. package/content/best-practices/testing-strategies.md +7 -2
  24. package/content/best-practices/troubleshooting-tips.md +27 -17
  25. package/content/extensions/components/api-reference.md +109 -323
  26. package/content/extensions/components/authentication/api.md +489 -602
  27. package/content/extensions/components/authentication/errors.md +135 -498
  28. package/content/extensions/components/authentication/index.md +89 -801
  29. package/content/extensions/components/authentication/usage.md +231 -955
  30. package/content/extensions/components/authorization/api.md +991 -644
  31. package/content/extensions/components/authorization/errors.md +204 -208
  32. package/content/extensions/components/authorization/getting-started.md +227 -0
  33. package/content/extensions/components/authorization/index.md +88 -795
  34. package/content/extensions/components/authorization/usage.md +219 -528
  35. package/content/extensions/components/health-check.md +77 -243
  36. package/content/extensions/components/index.md +24 -90
  37. package/content/extensions/components/mail/api.md +553 -285
  38. package/content/extensions/components/mail/errors.md +76 -62
  39. package/content/extensions/components/mail/index.md +111 -463
  40. package/content/extensions/components/mail/usage.md +139 -173
  41. package/content/extensions/components/request-tracker.md +70 -173
  42. package/content/extensions/components/socket-io/api.md +462 -785
  43. package/content/extensions/components/socket-io/errors.md +49 -51
  44. package/content/extensions/components/socket-io/index.md +69 -372
  45. package/content/extensions/components/socket-io/usage.md +212 -105
  46. package/content/extensions/components/static-asset/api.md +461 -141
  47. package/content/extensions/components/static-asset/errors.md +121 -53
  48. package/content/extensions/components/static-asset/index.md +84 -606
  49. package/content/extensions/components/static-asset/usage.md +184 -299
  50. package/content/extensions/components/template/index.md +3 -3
  51. package/content/extensions/components/websocket/api.md +311 -404
  52. package/content/extensions/components/websocket/errors.md +47 -56
  53. package/content/extensions/components/websocket/index.md +75 -407
  54. package/content/extensions/components/websocket/usage.md +120 -338
  55. package/content/extensions/helpers/cron/index.md +52 -160
  56. package/content/extensions/helpers/crypto/index.md +67 -480
  57. package/content/extensions/helpers/crypto/reference.md +528 -0
  58. package/content/extensions/helpers/env/index.md +64 -178
  59. package/content/extensions/helpers/error/index.md +286 -196
  60. package/content/extensions/helpers/index.md +61 -47
  61. package/content/extensions/helpers/inversion/index.md +76 -550
  62. package/content/extensions/helpers/inversion/reference.md +530 -0
  63. package/content/extensions/helpers/kafka/admin.md +23 -3
  64. package/content/extensions/helpers/kafka/compile-binary.md +83 -52
  65. package/content/extensions/helpers/kafka/consumer.md +65 -28
  66. package/content/extensions/helpers/kafka/examples.md +46 -253
  67. package/content/extensions/helpers/kafka/index.md +55 -617
  68. package/content/extensions/helpers/kafka/producer.md +156 -22
  69. package/content/extensions/helpers/kafka/schema-registry.md +59 -79
  70. package/content/extensions/helpers/logger/hf-logger.md +220 -0
  71. package/content/extensions/helpers/logger/index.md +78 -552
  72. package/content/extensions/helpers/logger/pino.md +105 -0
  73. package/content/extensions/helpers/logger/reference.md +937 -0
  74. package/content/extensions/helpers/network/api.md +276 -195
  75. package/content/extensions/helpers/network/index.md +87 -524
  76. package/content/extensions/helpers/queue/index.md +80 -897
  77. package/content/extensions/helpers/queue/reference.md +494 -0
  78. package/content/extensions/helpers/redis/index.md +86 -640
  79. package/content/extensions/helpers/redis/reference.md +784 -0
  80. package/content/extensions/helpers/secrets/index.md +136 -0
  81. package/content/extensions/helpers/socket-io/api.md +325 -204
  82. package/content/extensions/helpers/socket-io/index.md +79 -429
  83. package/content/extensions/helpers/storage/api.md +584 -464
  84. package/content/extensions/helpers/storage/index.md +80 -573
  85. package/content/extensions/helpers/types/index.md +75 -495
  86. package/content/extensions/helpers/types/reference.md +689 -0
  87. package/content/extensions/helpers/uid/index.md +176 -189
  88. package/content/extensions/helpers/websocket/api.md +366 -214
  89. package/content/extensions/helpers/websocket/index.md +68 -503
  90. package/content/extensions/helpers/worker-thread/index.md +62 -396
  91. package/content/extensions/helpers/worker-thread/reference.md +428 -0
  92. package/content/extensions/index.md +38 -39
  93. package/content/extensions/src-details/mcp-server.md +96 -548
  94. package/content/guides/core-concepts/persistent/datasources.md +2 -2
  95. package/content/guides/core-concepts/persistent/index.md +5 -1
  96. package/content/guides/core-concepts/persistent/models.md +1 -1
  97. package/content/guides/core-concepts/persistent/pglite.md +218 -0
  98. package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
  99. package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
  100. package/content/guides/core-concepts/persistent/search-typesense.md +28 -16
  101. package/content/guides/core-concepts/persistent/sqlite.md +296 -0
  102. package/content/guides/core-concepts/persistent/transactions.md +12 -11
  103. package/content/guides/core-concepts/secrets-vault.md +177 -0
  104. package/content/guides/core-concepts/services.md +1 -1
  105. package/content/guides/get-started/5-minute-quickstart.md +59 -206
  106. package/content/guides/get-started/philosophy.md +135 -670
  107. package/content/guides/get-started/setup.md +53 -74
  108. package/content/guides/migrations/redis-helpers-migration.md +5 -4
  109. package/content/guides/migrations/scoped-rbac-migration.md +5 -5
  110. package/content/guides/migrations/unified-connectors-migration.md +8 -7
  111. package/content/guides/tutorials/ecommerce-api.md +3 -8
  112. package/content/guides/tutorials/realtime-chat.md +1 -1
  113. package/content/references/base/application.md +64 -22
  114. package/content/references/base/components.md +3 -3
  115. package/content/references/base/connectors.md +79 -136
  116. package/content/references/base/controllers.md +12 -12
  117. package/content/references/base/datasources-reference.md +600 -0
  118. package/content/references/base/datasources.md +84 -444
  119. package/content/references/base/dependency-injection.md +25 -46
  120. package/content/references/base/filter-system/application-usage.md +95 -123
  121. package/content/references/base/filter-system/array-operators.md +33 -43
  122. package/content/references/base/filter-system/comparison-operators.md +55 -63
  123. package/content/references/base/filter-system/default-filter.md +144 -350
  124. package/content/references/base/filter-system/fields-order-pagination.md +116 -148
  125. package/content/references/base/filter-system/index.md +114 -253
  126. package/content/references/base/filter-system/json-filtering.md +52 -181
  127. package/content/references/base/filter-system/list-operators.md +28 -44
  128. package/content/references/base/filter-system/logical-operators.md +69 -114
  129. package/content/references/base/filter-system/null-operators.md +41 -98
  130. package/content/references/base/filter-system/pattern-matching.md +48 -51
  131. package/content/references/base/filter-system/quick-reference.md +93 -196
  132. package/content/references/base/filter-system/range-operators.md +22 -38
  133. package/content/references/base/filter-system/tips.md +70 -133
  134. package/content/references/base/filter-system/use-cases.md +173 -232
  135. package/content/references/base/grpc-controllers.md +53 -17
  136. package/content/references/base/index.md +5 -3
  137. package/content/references/base/middlewares.md +43 -28
  138. package/content/references/base/models-reference.md +886 -0
  139. package/content/references/base/models.md +81 -1452
  140. package/content/references/base/providers.md +8 -8
  141. package/content/references/base/repositories/advanced.md +281 -419
  142. package/content/references/base/repositories/index.md +84 -644
  143. package/content/references/base/repositories/mixins.md +25 -21
  144. package/content/references/base/repositories/relations.md +194 -375
  145. package/content/references/base/repositories/soft-deletable.md +67 -55
  146. package/content/references/base/secrets.md +267 -0
  147. package/content/references/base/services.md +8 -6
  148. package/content/references/configuration/environment-variables.md +73 -21
  149. package/content/references/configuration/index.md +51 -31
  150. package/content/references/index.md +1 -1
  151. package/content/references/quick-reference.md +3 -16
  152. package/content/references/utilities/crypto.md +35 -76
  153. package/content/references/utilities/date.md +33 -73
  154. package/content/references/utilities/duration.md +85 -0
  155. package/content/references/utilities/index.md +6 -2
  156. package/content/references/utilities/jsx-reference.md +298 -0
  157. package/content/references/utilities/jsx.md +82 -525
  158. package/content/references/utilities/module.md +81 -61
  159. package/content/references/utilities/parse.md +34 -64
  160. package/content/references/utilities/performance.md +33 -58
  161. package/content/references/utilities/promise.md +28 -62
  162. package/content/references/utilities/request.md +58 -218
  163. package/content/references/utilities/retry.md +139 -0
  164. package/content/references/utilities/schema.md +43 -137
  165. package/content/references/utilities/statuses-reference.md +361 -0
  166. package/content/references/utilities/statuses.md +63 -667
  167. package/dist/mcp-server/index.js +0 -0
  168. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
  169. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
  170. package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
  171. package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
  172. package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
  173. package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
  174. package/package.json +24 -23
@@ -1,231 +1,84 @@
1
+ ---
2
+ title: Worker Thread
3
+ description: Manage Node.js worker_threads with a pooled registry, lifecycle-event helpers, and two-way MessagePort communication
4
+ difficulty: intermediate
5
+ ---
6
+
1
7
  # Worker Thread
2
8
 
3
- Manage Node.js `worker_threads` for concurrent CPU-bound task execution with pooling, lifecycle management, and two-way communication via `MessagePort`.
9
+ The worker-thread helper wraps Node's `worker_threads`. It adds a pooled registry, lifecycle-event helpers, and a `MessagePort` bus for two-way communication between the main thread and a worker.
4
10
 
5
- ## Quick Reference
11
+ ## In one example
6
12
 
7
- | Class | Extends | Use Case |
8
- |-------|---------|----------|
9
- | `WorkerPoolHelper` | `BaseHelper` | Singleton registry that tracks and limits active worker instances |
10
- | `BaseWorkerHelper<MessageType>` | `AbstractWorkerHelper<MessageType>` | Wraps a `Worker` with event lifecycle hooks (online, exit, error, message) |
11
- | `BaseWorkerThreadHelper` | `AbstractWorkerThreadHelper` | Runs inside a worker thread; manages named `WorkerBus` channels |
12
- | `BaseWorkerBusHelper<IC, IP>` | `AbstractWorkerBusHelper<IC, IP>` | Bidirectional `MessagePort` communication with pre/post hooks |
13
- | `BaseWorkerMessageBusHandlerHelper<IC>` | `AbstractWorkerMessageBusHandlerHelper<IC>` | Defines event handlers for a worker bus (message, close, error, exit) |
13
+ The smallest real use: spawn a worker and register it in the singleton pool.
14
14
 
15
- | Item | Value |
16
- |------|-------|
17
- | **Package** | `@venizia/ignis-helpers` |
18
- | **Peer Dependency** | None (uses built-in `node:worker_threads`) |
19
- | **Runtimes** | Node.js (uses `node:worker_threads` and `node:os`) |
15
+ ```typescript
16
+ import { WorkerPoolHelper, BaseWorkerHelper } from '@venizia/ignis-helpers';
20
17
 
21
- #### Import Paths
18
+ const pool = WorkerPoolHelper.getInstance();
22
19
 
23
- ```typescript
24
- import {
25
- WorkerPoolHelper,
26
- BaseWorkerHelper,
27
- BaseWorkerThreadHelper,
28
- BaseWorkerBusHelper,
29
- BaseWorkerMessageBusHandlerHelper,
30
- } from '@venizia/ignis-helpers';
20
+ const worker = new BaseWorkerHelper<string>({
21
+ identifier: 'image-resizer',
22
+ path: './workers/image-resizer.js',
23
+ options: { workerData: { quality: 80 } },
24
+ });
31
25
 
32
- import type {
33
- IWorker,
34
- IWorkerThread,
35
- IWorkerBus,
36
- IWorkerMessageBusHandler,
37
- } from '@venizia/ignis-helpers';
26
+ pool.register({ key: 'image-resizer', worker });
38
27
  ```
39
28
 
40
- ## Creating an Instance
29
+ `WorkerPoolHelper` tracks active workers so the application never spawns more threads than it has CPU cores for.
41
30
 
42
- ### WorkerPoolHelper (Singleton)
31
+ ## How it works
43
32
 
44
- `WorkerPoolHelper` is a singleton registry for active workers. It limits the pool size to the number of CPU cores by default.
33
+ - **Main thread vs worker thread.** Two class families split by side.
34
+ - `BaseWorkerHelper` runs on the main thread and wraps a `Worker` instance.
35
+ - `BaseWorkerThreadHelper` runs inside the spawned worker script. It throws `[BaseWorker] Cannot start worker in MAIN_THREAD` if you construct it on the main thread instead.
36
+ - **Pool caps concurrency.** `WorkerPoolHelper` is a lazy singleton (`getInstance()`) that limits registrations to `os.cpus().length`. Past the limit, `register()` returns `false` and logs a warning - it never throws.
37
+ - **Lifecycle hooks, not raw events.**
38
+ - `BaseWorkerHelper` binds `online`, `exit`, `error`, `message`, and `messageerror` once in its constructor. Each has a default logging behavior, overridable per instance via `eventHandlers`.
39
+ - A synchronous throw inside a handler is caught and logged, not left to crash the process.
40
+ - **Two-way messaging via buses.** Inside a worker script, `BaseWorkerThreadHelper` manages named `BaseWorkerBusHelper` instances, each wrapping one `MessagePort`. A single worker can multiplex several independent channels this way, one per key.
45
41
 
46
- ```typescript
47
- import { WorkerPoolHelper } from '@venizia/ignis-helpers';
42
+ ## Common tasks
48
43
 
49
- // Get the singleton instance
50
- const pool = WorkerPoolHelper.getInstance();
51
- ```
44
+ ### Look up and message a registered worker
52
45
 
53
- You can also construct a custom instance directly:
46
+ `get()` and `has()` read the pool by key. `size()` reports how many workers are registered.
54
47
 
55
48
  ```typescript
56
- const pool = new WorkerPoolHelper({ ignoreMaxWarning: true });
49
+ const worker = pool.get<string>({ key: 'image-resizer' });
50
+ if (worker && pool.has({ key: 'image-resizer' })) {
51
+ worker.worker.postMessage('start');
52
+ }
57
53
  ```
58
54
 
59
- #### WorkerPoolHelper Constructor Options
55
+ ### Unregister and terminate a worker
60
56
 
61
- | Option | Type | Default | Description |
62
- |--------|------|---------|-------------|
63
- | `ignoreMaxWarning` | `boolean` | `false` | When `true`, allows registering workers beyond the CPU core count. When `false`, registration is skipped once the pool reaches the CPU core limit. |
57
+ `unregister()` calls `worker.terminate()` before removing the pool entry.
64
58
 
65
- > [!NOTE]
66
- > `WorkerPoolHelper.getInstance()` always creates the singleton with `ignoreMaxWarning: false`. To override this behavior, construct a new instance manually.
59
+ ```typescript
60
+ await pool.unregister({ key: 'image-resizer' });
61
+ ```
67
62
 
68
- ### BaseWorkerHelper (Main Thread Worker Wrapper)
63
+ ### Override lifecycle handlers
69
64
 
70
- `BaseWorkerHelper` creates a `Worker` from a file path and automatically binds all lifecycle events.
65
+ Pass `eventHandlers` to react to worker events instead of the default log lines.
71
66
 
72
67
  ```typescript
73
- import { BaseWorkerHelper } from '@venizia/ignis-helpers';
74
-
75
68
  const worker = new BaseWorkerHelper<MyMessageType>({
76
69
  identifier: 'data-processor',
77
70
  path: './workers/data-processor.js',
78
71
  options: { workerData: { batchSize: 100 } },
79
72
  eventHandlers: {
80
- onMessage: (opts) => {
81
- console.log('Received:', opts.message);
82
- },
83
- onError: (opts) => {
84
- console.error('Worker error:', opts.error);
85
- },
86
- },
87
- });
88
- ```
89
-
90
- #### BaseWorkerHelper Constructor Options
91
-
92
- | Option | Type | Default | Description |
93
- |--------|------|---------|-------------|
94
- | `identifier` | `string` | -- | A unique name for this worker instance, used in log output. Required. |
95
- | `path` | `string \| URL` | -- | Path to the worker script file. Required. |
96
- | `options` | `WorkerOptions` | -- | Node.js `WorkerOptions` passed directly to `new Worker()`. Required. Supports `workerData`, `transferList`, `env`, etc. |
97
- | `scope` | `string` | `'BaseWorkerHelper'` | Accepted but currently ignored -- the constructor always sets the logger scope to `'BaseWorkerHelper'`. |
98
- | `eventHandlers` | `Partial<Pick<IWorker<MessageType>, ...>>` | `undefined` | Optional overrides for lifecycle event callbacks. Any handler not provided falls back to default logging behavior. |
99
-
100
- #### Event Handler Overrides
101
-
102
- | Handler | Signature | Default Behavior |
103
- |---------|-----------|-----------------|
104
- | `onOnline` | `() => ValueOrPromise<void>` | Logs `"Worker ONLINE"` at info level |
105
- | `onExit` | `(opts: { code: string \| number }) => ValueOrPromise<void>` | Logs `"Worker EXIT"` with exit code at warn level |
106
- | `onError` | `(opts: { error: Error }) => ValueOrPromise<void>` | Logs `"Worker ERROR"` with error at error level |
107
- | `onMessage` | `(opts: { message: MessageType }) => ValueOrPromise<void>` | Logs `"Worker MESSAGE"` with message at error level |
108
- | `onMessageError` | `(opts: { error: Error }) => ValueOrPromise<void>` | Logs `"Worker MESSAGE_ERROR"` with error at error level |
109
-
110
- ### BaseWorkerThreadHelper (Inside Worker Thread)
111
-
112
- `BaseWorkerThreadHelper` is used inside a worker script to manage named communication buses. It must be instantiated from within a worker thread -- constructing it on the main thread throws an error.
113
-
114
- ```typescript
115
- // Inside worker-script.js
116
- import { BaseWorkerThreadHelper } from '@venizia/ignis-helpers';
117
-
118
- const thread = new BaseWorkerThreadHelper({ scope: 'DataProcessor' });
119
- ```
120
-
121
- #### BaseWorkerThreadHelper Constructor Options
122
-
123
- | Option | Type | Default | Description |
124
- |--------|------|---------|-------------|
125
- | `scope` | `string` | -- | Logger scope and identifier for this worker thread. Required. |
126
-
127
- ### BaseWorkerBusHelper (MessagePort Communication)
128
-
129
- `BaseWorkerBusHelper` wraps a `MessagePort` to provide structured bidirectional messaging with lifecycle event handlers.
130
-
131
- ```typescript
132
- import { BaseWorkerBusHelper, BaseWorkerMessageBusHandlerHelper } from '@venizia/ignis-helpers';
133
- import { parentPort } from 'node:worker_threads';
134
-
135
- const handler = new BaseWorkerMessageBusHandlerHelper<IncomingMessage>({
136
- scope: 'MyBusHandler',
137
- onMessage: (opts) => {
138
- console.log('Received:', opts.message);
73
+ onMessage: opts => console.log('Received:', opts.message),
74
+ onError: opts => console.error('Worker error:', opts.error),
139
75
  },
140
76
  });
141
-
142
- const bus = new BaseWorkerBusHelper<IncomingMessage, OutgoingMessage>({
143
- scope: 'MyBus',
144
- port: parentPort!,
145
- busHandler: handler,
146
- });
147
- ```
148
-
149
- #### BaseWorkerBusHelper Constructor Options
150
-
151
- | Option | Type | Default | Description |
152
- |--------|------|---------|-------------|
153
- | `scope` | `string` | -- | Logger scope and identifier. Required. |
154
- | `port` | `MessagePort` | -- | The `MessagePort` to bind for communication. Required. |
155
- | `busHandler` | `IWorkerMessageBusHandler<IConsumePayload>` | -- | Handler that receives incoming messages and lifecycle events. Required. |
156
-
157
- ### BaseWorkerMessageBusHandlerHelper
158
-
159
- Defines the event callbacks for a worker bus.
160
-
161
- ```typescript
162
- const handler = new BaseWorkerMessageBusHandlerHelper<MyPayload>({
163
- scope: 'ProcessorHandler',
164
- onMessage: (opts) => {
165
- console.log('Processing:', opts.message);
166
- },
167
- onError: (opts) => {
168
- console.error('Bus error:', opts.error);
169
- },
170
- });
171
- ```
172
-
173
- #### BaseWorkerMessageBusHandlerHelper Constructor Options
174
-
175
- | Option | Type | Default | Description |
176
- |--------|------|---------|-------------|
177
- | `scope` | `string` | -- | Logger scope and identifier. Required. |
178
- | `onMessage` | `(opts: { message: IConsumePayload }) => ValueOrPromise<void>` | -- | Handler called when a message is received on the port. Required. |
179
- | `onClose` | `() => ValueOrPromise<void>` | No-op `() => {}` | Handler called when the port is closed. |
180
- | `onError` | `(opts: { error: Error }) => ValueOrPromise<void>` | Logs error at error level | Handler called on port errors and message deserialization errors. |
181
- | `onExit` | `(opts: { exitCode: number \| string }) => ValueOrPromise<void>` | Logs exit code at warn level | Handler called when the port exits. |
182
-
183
- ## Usage
184
-
185
- ### Registering Workers in the Pool
186
-
187
- Use `WorkerPoolHelper` to track active workers. The pool prevents over-allocation by limiting registrations to the number of CPU cores.
188
-
189
- ```typescript
190
- const pool = WorkerPoolHelper.getInstance();
191
-
192
- const worker = new BaseWorkerHelper<string>({
193
- identifier: 'image-resizer',
194
- path: './workers/image-resizer.js',
195
- options: { workerData: { quality: 80 } },
196
- });
197
-
198
- // Register the worker in the pool
199
- pool.register({ key: 'image-resizer', worker });
200
-
201
- // Check pool state
202
- pool.has({ key: 'image-resizer' }); // true
203
- pool.size(); // 1
204
- ```
205
-
206
- > [!WARNING]
207
- > When the pool reaches the CPU core limit and `ignoreMaxWarning` is `false`, further `register()` calls are silently skipped with a warning log. No error is thrown.
208
-
209
- ### Retrieving and Unregistering Workers
210
-
211
- ```typescript
212
- const pool = WorkerPoolHelper.getInstance();
213
-
214
- // Retrieve a registered worker
215
- const worker = pool.get<string>({ key: 'image-resizer' });
216
- if (worker) {
217
- worker.worker.postMessage('start');
218
- }
219
-
220
- // Unregister terminates the worker and removes it from the pool
221
- await pool.unregister({ key: 'image-resizer' });
222
77
  ```
223
78
 
224
- `unregister()` calls `worker.terminate()` before removing the entry from the registry.
225
-
226
- ### Managing Worker Buses from Inside a Worker Thread
79
+ ### Bind a MessagePort bus inside a worker script
227
80
 
228
- `BaseWorkerThreadHelper` manages named communication channels (buses) within a worker script. Each bus is keyed by a string and wraps a `MessagePort`.
81
+ `BaseWorkerThreadHelper` keys buses by name so a worker can run several channels at once.
229
82
 
230
83
  ```typescript
231
84
  // worker-script.js
@@ -237,16 +90,11 @@ import {
237
90
  } from '@venizia/ignis-helpers';
238
91
 
239
92
  const thread = new BaseWorkerThreadHelper({ scope: 'MyWorker' });
93
+ const { port1 } = new MessageChannel();
240
94
 
241
- // Create a message channel
242
- const { port1, port2 } = new MessageChannel();
243
-
244
- // Create a handler and bus
245
95
  const handler = new BaseWorkerMessageBusHandlerHelper<{ task: string }>({
246
96
  scope: 'TaskHandler',
247
- onMessage: (opts) => {
248
- console.log('Task received:', opts.message.task);
249
- },
97
+ onMessage: opts => console.log('Task received:', opts.message.task),
250
98
  });
251
99
 
252
100
  const bus = new BaseWorkerBusHelper<{ task: string }, { result: string }>({
@@ -255,25 +103,14 @@ const bus = new BaseWorkerBusHelper<{ task: string }, { result: string }>({
255
103
  busHandler: handler,
256
104
  });
257
105
 
258
- // Bind and retrieve buses
259
106
  thread.bindWorkerBus({ key: 'tasks', bus });
260
- const taskBus = thread.getWorkerBus<{ task: string }, { result: string }>({
261
- key: 'tasks',
262
- });
263
107
  ```
264
108
 
265
- ### Sending Messages via a Worker Bus
109
+ ### Send a message with a transferable object
266
110
 
267
- `BaseWorkerBusHelper.postMessage()` sends data through the underlying `MessagePort`. It supports an optional `transferList` for zero-copy transfer of `ArrayBuffer` and similar objects.
111
+ `postMessage()` accepts an optional `transferList` for zero-copy transfer of `ArrayBuffer` and similar objects.
268
112
 
269
113
  ```typescript
270
- // Send a simple message
271
- bus.postMessage({
272
- message: { result: 'processed' },
273
- transferList: undefined,
274
- });
275
-
276
- // Send with transferable objects (zero-copy)
277
114
  const buffer = new ArrayBuffer(1024);
278
115
  bus.postMessage({
279
116
  message: { result: 'binary-data' },
@@ -281,190 +118,19 @@ bus.postMessage({
281
118
  });
282
119
  ```
283
120
 
284
- #### Pre/Post Message Hooks
285
-
286
- `BaseWorkerBusHelper` supports optional `onBeforePostMessage` and `onAfterPostMessage` hooks. These are undefined by default but can be assigned after construction.
287
-
288
- ```typescript
289
- bus.onBeforePostMessage = (opts) => {
290
- console.log('About to send:', opts.message);
291
- };
292
-
293
- bus.onAfterPostMessage = (opts) => {
294
- console.log('Sent:', opts.message);
295
- };
296
- ```
297
-
298
- ### Unbinding a Worker Bus
299
-
300
- Remove a bus from the worker thread and clean up its port listeners:
301
-
302
- ```typescript
303
- thread.unbindWorkerBus({ key: 'tasks' });
304
- ```
305
-
306
- This calls `port.removeAllListeners()` on the bus's port before deleting it from the registry.
307
-
308
- ### Subclassing AbstractWorkerHelper
309
-
310
- For full control, extend `AbstractWorkerHelper` and implement all lifecycle methods directly:
311
-
312
- ```typescript
313
- import { AbstractWorkerHelper } from '@venizia/ignis-helpers';
314
-
315
- class CustomWorker extends AbstractWorkerHelper<MyMessage> {
316
- onOnline() {
317
- // Custom online handling
318
- }
319
-
320
- onExit(opts: { code: string | number }) {
321
- // Custom exit handling, e.g., restart logic
322
- }
323
-
324
- onError(opts: { error: Error }) {
325
- // Custom error handling
326
- }
327
-
328
- onMessage(opts: { message: MyMessage }) {
329
- // Custom message processing
330
- }
331
-
332
- onMessageError(opts: { error: Error }) {
333
- // Custom message error handling
334
- }
335
- }
336
- ```
337
-
338
- ## API Summary
339
-
340
- ### WorkerPoolHelper
341
-
342
- | Method | Signature | Description |
343
- |--------|-----------|-------------|
344
- | `getInstance` | `static getInstance(): WorkerPoolHelper` | Returns the singleton pool instance (creates one if needed) |
345
- | `register` | `register<MessageType>(opts: { key: string; worker: IWorker<MessageType> }): void` | Adds a worker to the pool. Skipped if key exists or pool is at CPU limit |
346
- | `unregister` | `async unregister(opts: { key: string }): Promise<void>` | Terminates the worker and removes it from the pool |
347
- | `get` | `get<MessageType>(opts: { key: string }): IWorker<MessageType> \| undefined` | Retrieves a registered worker by key |
348
- | `has` | `has(opts: { key: string }): boolean` | Checks if a worker is registered under the given key |
349
- | `size` | `size(): number` | Returns the number of currently registered workers |
350
-
351
- ### BaseWorkerHelper
352
-
353
- | Method | Signature | Description |
354
- |--------|-----------|-------------|
355
- | `onOnline` | `onOnline(): ValueOrPromise<void>` | Called when the worker thread comes online |
356
- | `onExit` | `onExit(opts: { code: string \| number }): ValueOrPromise<void>` | Called when the worker exits |
357
- | `onError` | `onError(opts: { error: Error }): ValueOrPromise<void>` | Called on worker errors |
358
- | `onMessage` | `onMessage(opts: { message: MessageType }): ValueOrPromise<void>` | Called when a message is received from the worker |
359
- | `onMessageError` | `onMessageError(opts: { error: Error }): ValueOrPromise<void>` | Called on message deserialization errors |
360
- | `binding` | `binding(): void` | Binds all event handlers to the internal `Worker` instance. Called automatically by the constructor |
361
-
362
- ### BaseWorkerThreadHelper
363
-
364
- | Method | Signature | Description |
365
- |--------|-----------|-------------|
366
- | `bindWorkerBus` | `bindWorkerBus<IC, IP>(opts: { key: string; bus: IWorkerBus<IC, IP> }): void` | Registers a bus under the given key. Skipped with warning if key already exists |
367
- | `unbindWorkerBus` | `unbindWorkerBus(opts: { key: string }): void` | Removes a bus and calls `port.removeAllListeners()`. Warns if key not found |
368
- | `getWorkerBus` | `getWorkerBus<IC, IP>(opts: { key: string }): IWorkerBus<IC, IP>` | Returns the bus for the given key. Throws if not found |
369
-
370
- ### BaseWorkerBusHelper
371
-
372
- | Method | Signature | Description |
373
- |--------|-----------|-------------|
374
- | `postMessage` | `postMessage(opts: { message: IP; transferList: readonly Transferable[] \| undefined }): ValueOrPromise<void>` | Sends a message through the port, optionally with transferable objects |
375
- | `onBeforePostMessage` | `onBeforePostMessage?(opts: { message: IP }): ValueOrPromise<void>` | Optional hook called before posting a message |
376
- | `onAfterPostMessage` | `onAfterPostMessage?(opts: { message: IP }): ValueOrPromise<void>` | Optional hook called after posting a message |
377
-
378
- ## Troubleshooting
379
-
380
- ### "[BaseWorker] Cannot start worker in MAIN_THREAD"
381
-
382
- **Cause:** `BaseWorkerThreadHelper` was instantiated on the main thread. This class is designed to run only inside a worker thread (where `isMainThread` from `node:worker_threads` is `false`).
383
-
384
- **Fix:** Only create `BaseWorkerThreadHelper` instances inside worker scripts that are spawned via `new Worker(path)`:
385
-
386
- ```typescript
387
- // worker-script.js (spawned by the main thread)
388
- import { BaseWorkerThreadHelper } from '@venizia/ignis-helpers';
389
-
390
- const thread = new BaseWorkerThreadHelper({ scope: 'MyWorker' }); // OK here
391
- ```
392
-
393
- ### "[binding] Invalid worker instance to bind event handlers"
394
-
395
- **Cause:** `BaseWorkerHelper.binding()` was called but the internal `Worker` instance is null or undefined. This can occur if the worker script path is invalid and the `Worker` constructor fails.
396
-
397
- **Fix:** Ensure the `path` passed to `BaseWorkerHelper` points to a valid, existing JavaScript file:
398
-
399
- ```typescript
400
- const worker = new BaseWorkerHelper({
401
- identifier: 'my-worker',
402
- path: './workers/my-worker.js', // Must exist and be a valid worker script
403
- options: {},
404
- });
405
- ```
406
-
407
- ### "[register] Invalid worker registry instance"
408
-
409
- **Cause:** `WorkerPoolHelper.register()` was called but the internal registry `Map` is null or undefined. This is a defensive check that should not occur under normal usage.
410
-
411
- **Fix:** Ensure you are using either `WorkerPoolHelper.getInstance()` or `new WorkerPoolHelper()` which both initialize the registry correctly.
412
-
413
- ### "[getWorkerBus] Not found worker bus | key: {key}"
414
-
415
- **Cause:** `BaseWorkerThreadHelper.getWorkerBus()` was called with a key that has not been registered via `bindWorkerBus()`.
416
-
417
- **Fix:** Verify the bus was bound before retrieving it:
418
-
419
- ```typescript
420
- thread.bindWorkerBus({ key: 'my-bus', bus: myBus });
421
-
422
- // Now safe to retrieve
423
- const bus = thread.getWorkerBus({ key: 'my-bus' });
424
- ```
425
-
426
- ### "Failed to post message to main | Invalid parentPort!"
427
-
428
- **Cause:** `BaseWorkerBusHelper.postMessage()` was called but the `port` property is null or undefined. This typically means the bus was constructed with an invalid `MessagePort`. Note this is logged at error level, not thrown -- the message is silently dropped.
429
-
430
- **Fix:** Ensure a valid `MessagePort` (e.g., `parentPort` from `node:worker_threads` or a port from `new MessageChannel()`) is passed to the constructor:
431
-
432
- ```typescript
433
- import { parentPort } from 'node:worker_threads';
434
-
435
- const bus = new BaseWorkerBusHelper({
436
- scope: 'MyBus',
437
- port: parentPort!, // Must be a valid MessagePort
438
- busHandler: handler,
439
- });
440
- ```
441
-
442
- ### Worker pool silently skips registration
443
-
444
- **Cause:** The pool has reached the CPU core limit and `ignoreMaxWarning` is `false` (the default for `getInstance()`).
445
-
446
- **Fix:** Either unregister unused workers first, or create a pool with `ignoreMaxWarning: true`:
447
-
448
- ```typescript
449
- // Option 1: Free up pool slots
450
- await pool.unregister({ key: 'old-worker' });
451
- pool.register({ key: 'new-worker', worker: newWorker });
452
-
453
- // Option 2: Allow exceeding the limit
454
- const pool = new WorkerPoolHelper({ ignoreMaxWarning: true });
455
- ```
121
+ Every constructor option, event-handler default, pre/post message hook, and error message is in the [Full reference](/extensions/helpers/worker-thread/reference).
456
122
 
457
- ## See Also
123
+ ## See also
458
124
 
459
- - **Related Concepts:**
460
- - [Services](/guides/core-concepts/services) -- Running background workers within services
461
- - [Application](/guides/core-concepts/application/) -- Spawning workers during application lifecycle
125
+ - [Full reference](/extensions/helpers/worker-thread/reference) - every constructor option, method signature, and troubleshooting case
126
+ - [Queue Helper](/extensions/helpers/queue/) - message-queue processing as an alternative to worker threads
127
+ - [Services](/guides/core-concepts/services) - running background workers within services
128
+ - [Application](/guides/core-concepts/application/) - spawning workers during application lifecycle
129
+ - [Node.js Worker Threads](https://nodejs.org/api/worker_threads.html) - underlying Node.js API
462
130
 
463
- - **Other Helpers:**
464
- - [Helpers Index](../index) -- All available helpers
465
- - [Queue Helper](../queue/) -- Message queue processing as an alternative to worker threads
131
+ **Files:**
466
132
 
467
- - **External Resources:**
468
- - [Node.js Worker Threads](https://nodejs.org/api/worker_threads.html) -- Official `worker_threads` documentation
469
- - [MessagePort API](https://nodejs.org/api/worker_threads.html#class-messageport) -- Underlying port communication
470
- - [Transferable Objects](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects) -- Zero-copy data transfer
133
+ - [`packages/helpers/src/modules/worker-thread/base.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/worker-thread/base.ts) - `AbstractWorkerHelper`, `BaseWorkerHelper`, `AbstractWorkerThreadHelper`, `BaseWorkerThreadHelper`
134
+ - [`packages/helpers/src/modules/worker-thread/worker-bus.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/worker-thread/worker-bus.ts) - `AbstractWorkerBusHelper`, `BaseWorkerBusHelper`, `AbstractWorkerMessageBusHandlerHelper`, `BaseWorkerMessageBusHandlerHelper`
135
+ - [`packages/helpers/src/modules/worker-thread/worker-pool.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/worker-thread/worker-pool.ts) - `WorkerPoolHelper`
136
+ - [`packages/helpers/src/modules/worker-thread/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/worker-thread/types.ts) - `IWorker`, `IWorkerThread`, `IWorkerBus`, `IWorkerMessageBusHandler`