@venizia/ignis-docs 0.0.5 → 0.0.6-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/package.json +1 -1
- package/wiki/best-practices/architectural-patterns.md +0 -2
- package/wiki/best-practices/architecture-decisions.md +0 -8
- package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
- package/wiki/best-practices/code-style-standards/index.md +0 -1
- package/wiki/best-practices/code-style-standards/tooling.md +0 -3
- package/wiki/best-practices/contribution-workflow.md +12 -12
- package/wiki/best-practices/index.md +4 -14
- package/wiki/best-practices/performance-optimization.md +3 -3
- package/wiki/best-practices/security-guidelines.md +2 -2
- package/wiki/best-practices/troubleshooting-tips.md +1 -1
- package/wiki/guides/core-concepts/application/bootstrapping.md +6 -7
- package/wiki/guides/core-concepts/components-guide.md +1 -1
- package/wiki/guides/core-concepts/components.md +2 -2
- package/wiki/guides/core-concepts/dependency-injection.md +4 -5
- package/wiki/guides/core-concepts/persistent/datasources.md +4 -5
- package/wiki/guides/core-concepts/services.md +1 -1
- package/wiki/guides/get-started/5-minute-quickstart.md +4 -5
- package/wiki/guides/get-started/philosophy.md +12 -24
- package/wiki/guides/index.md +2 -9
- package/wiki/guides/reference/mcp-docs-server.md +13 -13
- package/wiki/guides/tutorials/building-a-crud-api.md +10 -10
- package/wiki/guides/tutorials/complete-installation.md +11 -12
- package/wiki/guides/tutorials/ecommerce-api.md +3 -3
- package/wiki/guides/tutorials/realtime-chat.md +6 -6
- package/wiki/guides/tutorials/testing.md +4 -5
- package/wiki/index.md +8 -14
- package/wiki/references/base/bootstrapping.md +0 -3
- package/wiki/references/base/components.md +2 -2
- package/wiki/references/base/controllers.md +0 -1
- package/wiki/references/base/datasources.md +1 -1
- package/wiki/references/base/dependency-injection.md +2 -2
- package/wiki/references/base/filter-system/default-filter.md +2 -3
- package/wiki/references/base/filter-system/index.md +1 -1
- package/wiki/references/base/filter-system/quick-reference.md +0 -14
- package/wiki/references/base/middlewares.md +0 -8
- package/wiki/references/base/providers.md +0 -9
- package/wiki/references/base/repositories/advanced.md +1 -1
- package/wiki/references/base/repositories/mixins.md +2 -3
- package/wiki/references/base/services.md +0 -1
- package/wiki/references/components/authentication/api.md +444 -0
- package/wiki/references/components/authentication/errors.md +177 -0
- package/wiki/references/components/authentication/index.md +571 -0
- package/wiki/references/components/authentication/usage.md +781 -0
- package/wiki/references/components/health-check.md +292 -103
- package/wiki/references/components/index.md +14 -12
- package/wiki/references/components/mail/api.md +505 -0
- package/wiki/references/components/mail/errors.md +176 -0
- package/wiki/references/components/mail/index.md +535 -0
- package/wiki/references/components/mail/usage.md +404 -0
- package/wiki/references/components/request-tracker.md +229 -25
- package/wiki/references/components/socket-io/api.md +1051 -0
- package/wiki/references/components/socket-io/errors.md +119 -0
- package/wiki/references/components/socket-io/index.md +410 -0
- package/wiki/references/components/socket-io/usage.md +322 -0
- package/wiki/references/components/static-asset/api.md +261 -0
- package/wiki/references/components/static-asset/errors.md +89 -0
- package/wiki/references/components/static-asset/index.md +617 -0
- package/wiki/references/components/static-asset/usage.md +364 -0
- package/wiki/references/components/swagger.md +390 -110
- package/wiki/references/components/template/api-page.md +125 -0
- package/wiki/references/components/template/errors-page.md +100 -0
- package/wiki/references/components/template/index.md +104 -0
- package/wiki/references/components/template/setup-page.md +134 -0
- package/wiki/references/components/template/single-page.md +132 -0
- package/wiki/references/components/template/usage-page.md +127 -0
- package/wiki/references/components/websocket/api.md +508 -0
- package/wiki/references/components/websocket/errors.md +123 -0
- package/wiki/references/components/websocket/index.md +453 -0
- package/wiki/references/components/websocket/usage.md +475 -0
- package/wiki/references/helpers/cron/index.md +224 -0
- package/wiki/references/helpers/crypto/index.md +537 -0
- package/wiki/references/helpers/env/index.md +214 -0
- package/wiki/references/helpers/error/index.md +232 -0
- package/wiki/references/helpers/index.md +16 -15
- package/wiki/references/helpers/inversion/index.md +608 -0
- package/wiki/references/helpers/logger/index.md +600 -0
- package/wiki/references/helpers/network/api.md +986 -0
- package/wiki/references/helpers/network/index.md +620 -0
- package/wiki/references/helpers/queue/index.md +589 -0
- package/wiki/references/helpers/redis/index.md +495 -0
- package/wiki/references/helpers/socket-io/api.md +497 -0
- package/wiki/references/helpers/socket-io/index.md +513 -0
- package/wiki/references/helpers/storage/api.md +705 -0
- package/wiki/references/helpers/storage/index.md +583 -0
- package/wiki/references/helpers/template/index.md +66 -0
- package/wiki/references/helpers/template/single-page.md +126 -0
- package/wiki/references/helpers/testing/index.md +510 -0
- package/wiki/references/helpers/types/index.md +512 -0
- package/wiki/references/helpers/uid/index.md +272 -0
- package/wiki/references/helpers/websocket/api.md +736 -0
- package/wiki/references/helpers/websocket/index.md +574 -0
- package/wiki/references/helpers/worker-thread/index.md +470 -0
- package/wiki/references/index.md +2 -9
- package/wiki/references/quick-reference.md +3 -18
- package/wiki/references/utilities/jsx.md +1 -8
- package/wiki/references/utilities/statuses.md +0 -7
- package/wiki/references/components/authentication.md +0 -476
- package/wiki/references/components/mail.md +0 -687
- package/wiki/references/components/socket-io.md +0 -562
- package/wiki/references/components/static-asset.md +0 -1277
- package/wiki/references/helpers/cron.md +0 -108
- package/wiki/references/helpers/crypto.md +0 -132
- package/wiki/references/helpers/env.md +0 -83
- package/wiki/references/helpers/error.md +0 -97
- package/wiki/references/helpers/inversion.md +0 -176
- package/wiki/references/helpers/logger.md +0 -296
- package/wiki/references/helpers/network.md +0 -396
- package/wiki/references/helpers/queue.md +0 -150
- package/wiki/references/helpers/redis.md +0 -142
- package/wiki/references/helpers/socket-io.md +0 -932
- package/wiki/references/helpers/storage.md +0 -665
- package/wiki/references/helpers/testing.md +0 -133
- package/wiki/references/helpers/types.md +0 -167
- package/wiki/references/helpers/uid.md +0 -167
- package/wiki/references/helpers/worker-thread.md +0 -178
- package/wiki/references/src-details/boot.md +0 -379
- package/wiki/references/src-details/core.md +0 -263
- package/wiki/references/src-details/dev-configs.md +0 -298
- package/wiki/references/src-details/docs.md +0 -71
- package/wiki/references/src-details/helpers.md +0 -211
- package/wiki/references/src-details/index.md +0 -86
- package/wiki/references/src-details/inversion.md +0 -340
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
# Worker Thread
|
|
2
|
+
|
|
3
|
+
Manage Node.js `worker_threads` for concurrent CPU-bound task execution with pooling, lifecycle management, and two-way communication via `MessagePort`.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
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) |
|
|
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`) |
|
|
20
|
+
|
|
21
|
+
#### Import Paths
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import {
|
|
25
|
+
WorkerPoolHelper,
|
|
26
|
+
BaseWorkerHelper,
|
|
27
|
+
BaseWorkerThreadHelper,
|
|
28
|
+
BaseWorkerBusHelper,
|
|
29
|
+
BaseWorkerMessageBusHandlerHelper,
|
|
30
|
+
} from '@venizia/ignis-helpers';
|
|
31
|
+
|
|
32
|
+
import type {
|
|
33
|
+
IWorker,
|
|
34
|
+
IWorkerThread,
|
|
35
|
+
IWorkerBus,
|
|
36
|
+
IWorkerMessageBusHandler,
|
|
37
|
+
} from '@venizia/ignis-helpers';
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Creating an Instance
|
|
41
|
+
|
|
42
|
+
### WorkerPoolHelper (Singleton)
|
|
43
|
+
|
|
44
|
+
`WorkerPoolHelper` is a singleton registry for active workers. It limits the pool size to the number of CPU cores by default.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { WorkerPoolHelper } from '@venizia/ignis-helpers';
|
|
48
|
+
|
|
49
|
+
// Get the singleton instance
|
|
50
|
+
const pool = WorkerPoolHelper.getInstance();
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
You can also construct a custom instance directly:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const pool = new WorkerPoolHelper({ ignoreMaxWarning: true });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### WorkerPoolHelper Constructor Options
|
|
60
|
+
|
|
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. |
|
|
64
|
+
|
|
65
|
+
> [!NOTE]
|
|
66
|
+
> `WorkerPoolHelper.getInstance()` always creates the singleton with `ignoreMaxWarning: false`. To override this behavior, construct a new instance manually.
|
|
67
|
+
|
|
68
|
+
### BaseWorkerHelper (Main Thread Worker Wrapper)
|
|
69
|
+
|
|
70
|
+
`BaseWorkerHelper` creates a `Worker` from a file path and automatically binds all lifecycle events.
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { BaseWorkerHelper } from '@venizia/ignis-helpers';
|
|
74
|
+
|
|
75
|
+
const worker = new BaseWorkerHelper<MyMessageType>({
|
|
76
|
+
identifier: 'data-processor',
|
|
77
|
+
path: './workers/data-processor.js',
|
|
78
|
+
options: { workerData: { batchSize: 100 } },
|
|
79
|
+
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'` | Logger scope prefix. |
|
|
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);
|
|
139
|
+
},
|
|
140
|
+
});
|
|
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
|
+
```
|
|
223
|
+
|
|
224
|
+
`unregister()` calls `worker.terminate()` before removing the entry from the registry.
|
|
225
|
+
|
|
226
|
+
### Managing Worker Buses from Inside a Worker Thread
|
|
227
|
+
|
|
228
|
+
`BaseWorkerThreadHelper` manages named communication channels (buses) within a worker script. Each bus is keyed by a string and wraps a `MessagePort`.
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
// worker-script.js
|
|
232
|
+
import { MessageChannel } from 'node:worker_threads';
|
|
233
|
+
import {
|
|
234
|
+
BaseWorkerThreadHelper,
|
|
235
|
+
BaseWorkerBusHelper,
|
|
236
|
+
BaseWorkerMessageBusHandlerHelper,
|
|
237
|
+
} from '@venizia/ignis-helpers';
|
|
238
|
+
|
|
239
|
+
const thread = new BaseWorkerThreadHelper({ scope: 'MyWorker' });
|
|
240
|
+
|
|
241
|
+
// Create a message channel
|
|
242
|
+
const { port1, port2 } = new MessageChannel();
|
|
243
|
+
|
|
244
|
+
// Create a handler and bus
|
|
245
|
+
const handler = new BaseWorkerMessageBusHandlerHelper<{ task: string }>({
|
|
246
|
+
scope: 'TaskHandler',
|
|
247
|
+
onMessage: (opts) => {
|
|
248
|
+
console.log('Task received:', opts.message.task);
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const bus = new BaseWorkerBusHelper<{ task: string }, { result: string }>({
|
|
253
|
+
scope: 'TaskBus',
|
|
254
|
+
port: port1,
|
|
255
|
+
busHandler: handler,
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Bind and retrieve buses
|
|
259
|
+
thread.bindWorkerBus({ key: 'tasks', bus });
|
|
260
|
+
const taskBus = thread.getWorkerBus<{ task: string }, { result: string }>({
|
|
261
|
+
key: 'tasks',
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Sending Messages via a Worker Bus
|
|
266
|
+
|
|
267
|
+
`BaseWorkerBusHelper.postMessage()` sends data through the underlying `MessagePort`. It supports an optional `transferList` for zero-copy transfer of `ArrayBuffer` and similar objects.
|
|
268
|
+
|
|
269
|
+
```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
|
+
const buffer = new ArrayBuffer(1024);
|
|
278
|
+
bus.postMessage({
|
|
279
|
+
message: { result: 'binary-data' },
|
|
280
|
+
transferList: [buffer],
|
|
281
|
+
});
|
|
282
|
+
```
|
|
283
|
+
|
|
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`.
|
|
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
|
+
```
|
|
456
|
+
|
|
457
|
+
## See Also
|
|
458
|
+
|
|
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
|
|
462
|
+
|
|
463
|
+
- **Other Helpers:**
|
|
464
|
+
- [Helpers Index](../index) -- All available helpers
|
|
465
|
+
- [Queue Helper](../queue/) -- Message queue processing as an alternative to worker threads
|
|
466
|
+
|
|
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
|
package/wiki/references/index.md
CHANGED
|
@@ -5,37 +5,31 @@ Complete reference documentation for the Ignis framework. Find detailed API docs
|
|
|
5
5
|
<div class="guide-cards">
|
|
6
6
|
|
|
7
7
|
<a href="./base/" class="guide-card highlight">
|
|
8
|
-
<span class="guide-icon">🏗️</span>
|
|
9
8
|
<h3>Base Abstractions</h3>
|
|
10
9
|
<p>Application, Controller, Service, Repository, Model</p>
|
|
11
10
|
</a>
|
|
12
11
|
|
|
13
12
|
<a href="./components/" class="guide-card">
|
|
14
|
-
<span class="guide-icon">🧩</span>
|
|
15
13
|
<h3>Components</h3>
|
|
16
14
|
<p>Auth, Mail, Socket.IO, Swagger, Health Check</p>
|
|
17
15
|
</a>
|
|
18
16
|
|
|
19
17
|
<a href="./helpers/" class="guide-card">
|
|
20
|
-
<span class="guide-icon">🛠️</span>
|
|
21
18
|
<h3>Helpers</h3>
|
|
22
19
|
<p>Logger, Redis, Queue, Storage, Cron, Crypto</p>
|
|
23
20
|
</a>
|
|
24
21
|
|
|
25
22
|
<a href="./utilities/" class="guide-card">
|
|
26
|
-
<span class="guide-icon">⚙️</span>
|
|
27
23
|
<h3>Utilities</h3>
|
|
28
24
|
<p>Date, Parse, Promise, Schema, Performance</p>
|
|
29
25
|
</a>
|
|
30
26
|
|
|
31
27
|
<a href="./configuration/" class="guide-card">
|
|
32
|
-
<span class="guide-icon">📝</span>
|
|
33
28
|
<h3>Configuration</h3>
|
|
34
29
|
<p>Environment variables and settings</p>
|
|
35
30
|
</a>
|
|
36
31
|
|
|
37
32
|
<a href="./src-details/" class="guide-card">
|
|
38
|
-
<span class="guide-icon">📦</span>
|
|
39
33
|
<h3>Framework Internals</h3>
|
|
40
34
|
<p>Package structure and architecture</p>
|
|
41
35
|
</a>
|
|
@@ -111,9 +105,8 @@ Complete reference documentation for the Ignis framework. Find detailed API docs
|
|
|
111
105
|
|
|
112
106
|
</div>
|
|
113
107
|
|
|
114
|
-
|
|
115
|
-
Check out the [Getting Started Guide](/guides/) for step-by-step tutorials and the [Core Concepts](/guides/core-concepts/application/) for architectural explanations.
|
|
116
|
-
:::
|
|
108
|
+
> [!TIP] Looking for tutorials?
|
|
109
|
+
> Check out the [Getting Started Guide](/guides/) for step-by-step tutorials and the [Core Concepts](/guides/core-concepts/application/) for architectural explanations.
|
|
117
110
|
|
|
118
111
|
## Quick Examples
|
|
119
112
|
|
|
@@ -119,7 +119,6 @@ class User extends BaseEntity {
|
|
|
119
119
|
- `static tableName` - Database table name
|
|
120
120
|
- `static schema` - Drizzle schema definition
|
|
121
121
|
|
|
122
|
-
---
|
|
123
122
|
|
|
124
123
|
## Route Decorators
|
|
125
124
|
|
|
@@ -170,7 +169,6 @@ class UserController extends BaseController {
|
|
|
170
169
|
}
|
|
171
170
|
```
|
|
172
171
|
|
|
173
|
-
---
|
|
174
172
|
|
|
175
173
|
## Filter Operators
|
|
176
174
|
|
|
@@ -239,7 +237,6 @@ class UserController extends BaseController {
|
|
|
239
237
|
|----------|-------------|---------|
|
|
240
238
|
| `jsonPath` | Query JSON field | `{ metadata: { jsonPath: '$.user.name', eq: 'John' } }` |
|
|
241
239
|
|
|
242
|
-
---
|
|
243
240
|
|
|
244
241
|
## Common Filters
|
|
245
242
|
|
|
@@ -292,7 +289,6 @@ const users = await userRepo.find({
|
|
|
292
289
|
});
|
|
293
290
|
```
|
|
294
291
|
|
|
295
|
-
---
|
|
296
292
|
|
|
297
293
|
## Dependency Injection
|
|
298
294
|
|
|
@@ -329,7 +325,6 @@ class UserController extends BaseController {
|
|
|
329
325
|
const userService = app.get<UserService>('services.UserService');
|
|
330
326
|
```
|
|
331
327
|
|
|
332
|
-
---
|
|
333
328
|
|
|
334
329
|
## Common Imports
|
|
335
330
|
|
|
@@ -385,13 +380,6 @@ import {
|
|
|
385
380
|
|
|
386
381
|
// Queues
|
|
387
382
|
QueueHelper,
|
|
388
|
-
BullMQHelper,
|
|
389
|
-
|
|
390
|
-
// Cron
|
|
391
|
-
CronHelper,
|
|
392
|
-
|
|
393
|
-
// Storage
|
|
394
|
-
MinIOHelper,
|
|
395
383
|
|
|
396
384
|
// Crypto
|
|
397
385
|
hash,
|
|
@@ -400,6 +388,9 @@ import {
|
|
|
400
388
|
// HTTP
|
|
401
389
|
HTTP,
|
|
402
390
|
} from '@venizia/ignis-helpers';
|
|
391
|
+
import { BullMQHelper } from '@venizia/ignis-helpers/bullmq';
|
|
392
|
+
import { CronHelper } from '@venizia/ignis-helpers/cron';
|
|
393
|
+
import { MinIOHelper } from '@venizia/ignis-helpers/minio';
|
|
403
394
|
```
|
|
404
395
|
|
|
405
396
|
### Dependency Injection
|
|
@@ -412,7 +403,6 @@ import {
|
|
|
412
403
|
} from '@venizia/ignis-inversion';
|
|
413
404
|
```
|
|
414
405
|
|
|
415
|
-
---
|
|
416
406
|
|
|
417
407
|
## OpenAPI/Swagger
|
|
418
408
|
|
|
@@ -458,7 +448,6 @@ async getDashboard() {
|
|
|
458
448
|
}
|
|
459
449
|
```
|
|
460
450
|
|
|
461
|
-
---
|
|
462
451
|
|
|
463
452
|
## Status Codes
|
|
464
453
|
|
|
@@ -507,7 +496,6 @@ if (Statuses.isCompleted(order.status)) {
|
|
|
507
496
|
| `CANCELLED` | `'505_CANCELLED'` | Failed |
|
|
508
497
|
| `DELETED` | `'506_DELETED'` | Failed |
|
|
509
498
|
|
|
510
|
-
---
|
|
511
499
|
|
|
512
500
|
## Middlewares
|
|
513
501
|
|
|
@@ -537,7 +525,6 @@ app.onError(appErrorHandler({ logger: app.logger }));
|
|
|
537
525
|
app.notFound(notFoundHandler({ logger: app.logger }));
|
|
538
526
|
```
|
|
539
527
|
|
|
540
|
-
---
|
|
541
528
|
|
|
542
529
|
## Environment Variables
|
|
543
530
|
|
|
@@ -559,7 +546,6 @@ const port = EnvHelper.get('PORT', '3000');
|
|
|
559
546
|
const apiKey = EnvHelper.getRequired('API_KEY');
|
|
560
547
|
```
|
|
561
548
|
|
|
562
|
-
---
|
|
563
549
|
|
|
564
550
|
## Common Patterns
|
|
565
551
|
|
|
@@ -613,7 +599,6 @@ class UserRepository extends DefaultCRUDRepository<User> {
|
|
|
613
599
|
}
|
|
614
600
|
```
|
|
615
601
|
|
|
616
|
-
---
|
|
617
602
|
|
|
618
603
|
## See Also
|
|
619
604
|
|
|
@@ -86,7 +86,6 @@ const pageContent = htmlContent({
|
|
|
86
86
|
// }
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
---
|
|
90
89
|
|
|
91
90
|
## htmlResponse()
|
|
92
91
|
|
|
@@ -152,7 +151,6 @@ this.defineRoute({
|
|
|
152
151
|
});
|
|
153
152
|
```
|
|
154
153
|
|
|
155
|
-
---
|
|
156
154
|
|
|
157
155
|
## Usage Examples
|
|
158
156
|
|
|
@@ -311,7 +309,6 @@ export class AdminController extends BaseController {
|
|
|
311
309
|
}
|
|
312
310
|
```
|
|
313
311
|
|
|
314
|
-
---
|
|
315
312
|
|
|
316
313
|
## Comparison with JSON Utilities
|
|
317
314
|
|
|
@@ -332,7 +329,6 @@ export class AdminController extends BaseController {
|
|
|
332
329
|
| **Error Type** | `application/json` (4xx/5xx) | `application/json` (4xx/5xx) |
|
|
333
330
|
| **Use Case** | Web pages | REST APIs |
|
|
334
331
|
|
|
335
|
-
---
|
|
336
332
|
|
|
337
333
|
## Best Practices
|
|
338
334
|
|
|
@@ -447,7 +443,6 @@ async getBlogPost(c: TRouteContext) {
|
|
|
447
443
|
}
|
|
448
444
|
```
|
|
449
445
|
|
|
450
|
-
---
|
|
451
446
|
|
|
452
447
|
## Integration with Hono JSX
|
|
453
448
|
|
|
@@ -506,7 +501,6 @@ async getHome() {
|
|
|
506
501
|
}
|
|
507
502
|
```
|
|
508
503
|
|
|
509
|
-
---
|
|
510
504
|
|
|
511
505
|
## Common Pitfalls
|
|
512
506
|
|
|
@@ -562,14 +556,13 @@ async getUsers() {
|
|
|
562
556
|
}
|
|
563
557
|
```
|
|
564
558
|
|
|
565
|
-
---
|
|
566
559
|
|
|
567
560
|
## See Also
|
|
568
561
|
|
|
569
562
|
- **Related References:**
|
|
570
563
|
- [Schema Utility](./schema.md) - JSON content and response helpers
|
|
571
564
|
- [Controllers](../base/controllers.md) - Defining routes and handlers
|
|
572
|
-
- [OpenAPI Component](../components/swagger
|
|
565
|
+
- [OpenAPI Component](../components/swagger) - API documentation
|
|
573
566
|
|
|
574
567
|
- **External Resources:**
|
|
575
568
|
- [Hono JSX Documentation](https://hono.dev/guides/jsx)
|