@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
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
# Testing Helper
|
|
2
|
-
|
|
3
|
-
Structured test framework integrating with Node.js's native `node:test` module.
|
|
4
|
-
|
|
5
|
-
## Quick Reference
|
|
6
|
-
|
|
7
|
-
| Component | Purpose |
|
|
8
|
-
|-----------|---------|
|
|
9
|
-
| **TestPlan** | Organizes test suite with lifecycle hooks and shared context |
|
|
10
|
-
| **TestCase** | Single runnable test unit with metadata |
|
|
11
|
-
| **TestCaseHandler** | Encapsulates test execution and validation logic |
|
|
12
|
-
| **TestDescribe** | Runs test plans |
|
|
13
|
-
|
|
14
|
-
### Test Lifecycle Hooks
|
|
15
|
-
|
|
16
|
-
| Hook | When | Purpose |
|
|
17
|
-
|------|------|---------|
|
|
18
|
-
| `before` | Before all tests | Setup (e.g., start server, seed DB) |
|
|
19
|
-
| `after` | After all tests | Cleanup (e.g., close connections) |
|
|
20
|
-
| `beforeEach` | Before each test | Reset state |
|
|
21
|
-
| `afterEach` | After each test | Cleanup per test |
|
|
22
|
-
|
|
23
|
-
### TestCaseDecisions
|
|
24
|
-
|
|
25
|
-
| Decision | Meaning |
|
|
26
|
-
|----------|---------|
|
|
27
|
-
| `SUCCESS` | Test passed |
|
|
28
|
-
| `FAIL` | Test failed |
|
|
29
|
-
| `SKIP` | Test skipped |
|
|
30
|
-
|
|
31
|
-
## Creating a Test Plan
|
|
32
|
-
|
|
33
|
-
A test plan is the main entry point for a test suite. You define the scope, hooks, and test cases within the plan.
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
// __tests__/my-feature.test.ts
|
|
37
|
-
import { TestPlan, TestDescribe, TestCase, TestCaseHandler, TestCaseDecisions } from '@venizia/ignis';
|
|
38
|
-
|
|
39
|
-
// 1. Define a Test Case Handler
|
|
40
|
-
class MyTestHandler extends TestCaseHandler {
|
|
41
|
-
async execute() {
|
|
42
|
-
// Perform the action to be tested
|
|
43
|
-
return { result: 'some-value' };
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
getValidator() {
|
|
47
|
-
return (opts: { result: string }) => {
|
|
48
|
-
if (opts.result === 'some-value') {
|
|
49
|
-
return TestCaseDecisions.SUCCESS;
|
|
50
|
-
}
|
|
51
|
-
return TestCaseDecisions.FAIL;
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// 2. Create a Test Plan
|
|
57
|
-
const myTestPlan = TestPlan.newInstance({
|
|
58
|
-
scope: 'My Feature',
|
|
59
|
-
hooks: {
|
|
60
|
-
before: async () => console.log('Starting My Feature tests...'),
|
|
61
|
-
after: async () => console.log('Finished My Feature tests.'),
|
|
62
|
-
},
|
|
63
|
-
testCases: [
|
|
64
|
-
TestCase.withOptions({
|
|
65
|
-
code: 'MY-FEATURE-001',
|
|
66
|
-
description: 'It should return the correct value',
|
|
67
|
-
expectation: 'The result should be "some-value"',
|
|
68
|
-
handler: new MyTestHandler({ context: {} as any }), // Context is provided by the plan
|
|
69
|
-
}),
|
|
70
|
-
],
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// 3. Run the Test Plan
|
|
74
|
-
TestDescribe.withTestPlan({ testPlan: myTestPlan }).run();
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Shared Context
|
|
78
|
-
|
|
79
|
-
The `TestPlan` provides a `context` that can be used to share data between test cases and hooks. This is useful for setup tasks like creating a JWT token or seeding a database.
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
// __tests__/auth.test.ts
|
|
83
|
-
import { TestPlan, TestDescribe, TestCase, TestCaseHandler, ITestContext } from '@venizia/ignis';
|
|
84
|
-
|
|
85
|
-
// A handler that uses the context
|
|
86
|
-
class SecureApiHandler extends TestCaseHandler<{ token: string }> {
|
|
87
|
-
async execute() {
|
|
88
|
-
const token = this.context.getSync<{ token: string }>({ key: 'token' });
|
|
89
|
-
const response = await app.request('/api/secure-data', {
|
|
90
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
91
|
-
});
|
|
92
|
-
return { status: response.status };
|
|
93
|
-
}
|
|
94
|
-
// ... validator
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const authTestPlan = TestPlan.newInstance({
|
|
98
|
-
scope: 'Authentication',
|
|
99
|
-
hooks: {
|
|
100
|
-
before: async (context: ITestContext<{ token: string }>) => {
|
|
101
|
-
// Generate a token and bind it to the context
|
|
102
|
-
const token = await generateTestToken();
|
|
103
|
-
context.bind({ key: 'token', value: token });
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
testCases: [
|
|
107
|
-
TestCase.withOptions({
|
|
108
|
-
// ...
|
|
109
|
-
handler: new SecureApiHandler({ context: {} as any }),
|
|
110
|
-
}),
|
|
111
|
-
],
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
TestDescribe.withTestPlan({ testPlan: authTestPlan }).run();
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## See Also
|
|
118
|
-
|
|
119
|
-
- **Related Concepts:**
|
|
120
|
-
- [Dependency Injection](/guides/core-concepts/dependency-injection) - Testing with DI
|
|
121
|
-
- [Application](/guides/core-concepts/application/) - Application lifecycle in tests
|
|
122
|
-
|
|
123
|
-
- **Other Helpers:**
|
|
124
|
-
- [Helpers Index](./index) - All available helpers
|
|
125
|
-
|
|
126
|
-
- **External Resources:**
|
|
127
|
-
- [Node.js Test Runner](https://nodejs.org/api/test.html) - Native test module
|
|
128
|
-
|
|
129
|
-
- **Tutorials:**
|
|
130
|
-
- [Testing Guide](/guides/tutorials/testing) - Complete testing tutorial
|
|
131
|
-
|
|
132
|
-
- **Best Practices:**
|
|
133
|
-
- [Troubleshooting Tips](/best-practices/troubleshooting-tips) - Debugging tests
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
# Common Types
|
|
2
|
-
|
|
3
|
-
Utility types and helper functions for common TypeScript patterns.
|
|
4
|
-
|
|
5
|
-
## Value Resolution Types
|
|
6
|
-
|
|
7
|
-
Types for lazy/deferred value resolution patterns.
|
|
8
|
-
|
|
9
|
-
### TResolver / TAsyncResolver
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
type TResolver<T> = (...args: any[]) => T;
|
|
13
|
-
type TAsyncResolver<T> = (...args: any[]) => T | Promise<T>;
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
Function types that resolve to a value. `TAsyncResolver` supports async functions.
|
|
17
|
-
|
|
18
|
-
### TValueOrResolver / TValueOrAsyncResolver
|
|
19
|
-
|
|
20
|
-
```typescript
|
|
21
|
-
type TValueOrResolver<T> = T | TResolver<T>;
|
|
22
|
-
type TValueOrAsyncResolver<T> = T | TAsyncResolver<T>;
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Union types allowing either a direct value or a resolver function.
|
|
26
|
-
|
|
27
|
-
**Usage:**
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
import { TValueOrAsyncResolver, resolveValueAsync } from '@venizia/ignis-helpers';
|
|
31
|
-
|
|
32
|
-
interface DatabaseConfig {
|
|
33
|
-
host: string;
|
|
34
|
-
port: number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
type ConfigOption = TValueOrAsyncResolver<DatabaseConfig>;
|
|
38
|
-
|
|
39
|
-
// Direct value
|
|
40
|
-
const config1: ConfigOption = { host: 'localhost', port: 5432 };
|
|
41
|
-
|
|
42
|
-
// Sync resolver
|
|
43
|
-
const config2: ConfigOption = () => ({ host: 'localhost', port: 5432 });
|
|
44
|
-
|
|
45
|
-
// Async resolver
|
|
46
|
-
const config3: ConfigOption = async () => {
|
|
47
|
-
const config = await fetchConfigFromVault();
|
|
48
|
-
return config;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
// Resolve any of the above
|
|
52
|
-
const resolved = await resolveValueAsync(config3);
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### resolveValue / resolveValueAsync
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
const resolveValue: <T>(valueOrResolver: TValueOrResolver<T>) => T;
|
|
59
|
-
const resolveValueAsync: <T>(valueOrResolver: TValueOrAsyncResolver<T>) => Promise<T>;
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Helper functions to resolve lazy values. They handle:
|
|
63
|
-
- **Direct values**: returned as-is
|
|
64
|
-
- **Class constructors**: returned as-is (not invoked)
|
|
65
|
-
- **Resolver functions**: invoked and result returned
|
|
66
|
-
|
|
67
|
-
## Nullable Types
|
|
68
|
-
|
|
69
|
-
### TNullable
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
type TNullable<T> = T | undefined | null;
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Makes a type nullable (can be `undefined` or `null`).
|
|
76
|
-
|
|
77
|
-
### ValueOrPromise
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
type ValueOrPromise<T> = T | Promise<T>;
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
A value that may or may not be wrapped in a Promise.
|
|
84
|
-
|
|
85
|
-
## Class Types
|
|
86
|
-
|
|
87
|
-
### TConstructor / TAbstractConstructor
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
type TConstructor<T> = new (...args: any[]) => T;
|
|
91
|
-
type TAbstractConstructor<T> = abstract new (...args: any[]) => T;
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Types representing class constructors.
|
|
95
|
-
|
|
96
|
-
### TClass / TAbstractClass
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
type TClass<T> = TConstructor<T> & { [property: string]: any };
|
|
100
|
-
type TAbstractClass<T> = TAbstractConstructor<T> & { [property: string]: any };
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Class types with static properties.
|
|
104
|
-
|
|
105
|
-
### TMixinTarget / TAbstractMixinTarget
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
type TMixinTarget<T> = TConstructor<{ [P in keyof T]: T[P] }>;
|
|
109
|
-
type TAbstractMixinTarget<T> = TAbstractConstructor<{ [P in keyof T]: T[P] }>;
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Types for mixin pattern targets.
|
|
113
|
-
|
|
114
|
-
## Object Utility Types
|
|
115
|
-
|
|
116
|
-
### ValueOf
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
type ValueOf<T> = T[keyof T];
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Extracts the value types from an object type.
|
|
123
|
-
|
|
124
|
-
### ValueOptional / ValueOptionalExcept
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
type ValueOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
128
|
-
type ValueOptionalExcept<T, K extends keyof T> = Pick<T, K> & Partial<Omit<T, K>>;
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Make specific keys optional while keeping others required, or vice versa.
|
|
132
|
-
|
|
133
|
-
### TPrettify
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
type TPrettify<T> = { [K in keyof T]: T[K] } & {};
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Flattens intersection types for better IDE display.
|
|
140
|
-
|
|
141
|
-
## Const Value Types
|
|
142
|
-
|
|
143
|
-
### TStringConstValue / TNumberConstValue / TConstValue
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
type TStringConstValue<T extends TClass<any>> = Extract<ValueOf<T>, string>;
|
|
147
|
-
type TNumberConstValue<T extends TClass<any>> = Extract<ValueOf<T>, number>;
|
|
148
|
-
type TConstValue<T extends TClass<any>> = Extract<ValueOf<T>, string | number>;
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Extract constant value types from a class.
|
|
152
|
-
|
|
153
|
-
## See Also
|
|
154
|
-
|
|
155
|
-
- **Related Concepts:**
|
|
156
|
-
- [Dependency Injection](/guides/core-concepts/dependency-injection) - DI types and patterns
|
|
157
|
-
- [Repositories](/guides/core-concepts/persistent/repositories) - Repository mixins use these types
|
|
158
|
-
|
|
159
|
-
- **Other Helpers:**
|
|
160
|
-
- [Helpers Index](./index) - All available helpers
|
|
161
|
-
|
|
162
|
-
- **References:**
|
|
163
|
-
- [Repository Mixins](/references/base/repositories/mixins) - Uses mixin types
|
|
164
|
-
- [Utilities Index](/references/utilities/index) - Type utilities
|
|
165
|
-
|
|
166
|
-
- **Best Practices:**
|
|
167
|
-
- [Architectural Patterns](/best-practices/architectural-patterns) - TypeScript patterns
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
# UID Helper
|
|
2
|
-
|
|
3
|
-
Snowflake ID generator with Base62 encoding for generating unique, time-sortable IDs suitable for distributed systems.
|
|
4
|
-
|
|
5
|
-
## Quick Reference
|
|
6
|
-
|
|
7
|
-
| Class | Purpose | Key Features |
|
|
8
|
-
|-------|---------|--------------|
|
|
9
|
-
| **SnowflakeConfig** | Configuration constants | Bit structure, limits, defaults |
|
|
10
|
-
| **SnowflakeUidHelper** | ID generation | Snowflake IDs, Base62 encoding/decoding |
|
|
11
|
-
|
|
12
|
-
### Snowflake ID Structure (70 bits)
|
|
13
|
-
|
|
14
|
-
| Component | Bits | Range | Purpose |
|
|
15
|
-
|-----------|------|-------|---------|
|
|
16
|
-
| Timestamp | 48 | ~8,919 years | Time since epoch |
|
|
17
|
-
| Worker ID | 10 | 0-1023 | Unique worker identifier |
|
|
18
|
-
| Sequence | 12 | 0-4095 | IDs per millisecond |
|
|
19
|
-
|
|
20
|
-
### Key Specifications
|
|
21
|
-
|
|
22
|
-
| Spec | Value |
|
|
23
|
-
|------|-------|
|
|
24
|
-
| Base62 Output | 10-12 characters |
|
|
25
|
-
| Throughput | 4,096,000 IDs/second/worker |
|
|
26
|
-
| Max Workers | 1024 |
|
|
27
|
-
| Lifespan | Until ~10,944 AD |
|
|
28
|
-
| Default Epoch | 2025-01-01 00:00:00 UTC |
|
|
29
|
-
|
|
30
|
-
## Basic Usage
|
|
31
|
-
|
|
32
|
-
### Creating an Instance
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
import { SnowflakeUidHelper, SnowflakeConfig } from '@venizia/ignis-helpers';
|
|
36
|
-
|
|
37
|
-
// Use defaults (workerId: 199, epoch: 2025-01-01 00:00:00 UTC)
|
|
38
|
-
const generator = new SnowflakeUidHelper();
|
|
39
|
-
|
|
40
|
-
// Or with custom values
|
|
41
|
-
const customGenerator = new SnowflakeUidHelper({
|
|
42
|
-
workerId: 123,
|
|
43
|
-
epoch: BigInt(1735689600000),
|
|
44
|
-
});
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Generating IDs
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
// Generate Base62 encoded ID (recommended for most use cases)
|
|
51
|
-
const id = generator.nextId();
|
|
52
|
-
// => e.g., "9du1sJXO88"
|
|
53
|
-
|
|
54
|
-
// Generate raw Snowflake ID as bigint
|
|
55
|
-
const snowflakeId = generator.nextSnowflake();
|
|
56
|
-
// => e.g., 130546360012247045n
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Base62 Encoding/Decoding
|
|
60
|
-
|
|
61
|
-
### Encode a BigInt to Base62
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
const encoded = generator.encodeBase62(130546360012247045n);
|
|
65
|
-
// => "9du1sJXO88"
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Decode Base62 to BigInt
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
const decoded = generator.decodeBase62("9du1sJXO88");
|
|
72
|
-
// => 130546360012247045n
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Parsing and Extracting Components
|
|
76
|
-
|
|
77
|
-
### Parse a Base62 ID
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
const parsed = generator.parseId("9du1sJXO88");
|
|
81
|
-
// => {
|
|
82
|
-
// raw: 130546360012247045n,
|
|
83
|
-
// timestamp: Date,
|
|
84
|
-
// workerId: 199,
|
|
85
|
-
// sequence: 0
|
|
86
|
-
// }
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Extract Individual Components
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
const snowflakeId = generator.nextSnowflake();
|
|
93
|
-
|
|
94
|
-
// Extract timestamp
|
|
95
|
-
const timestamp = generator.extractTimestamp(snowflakeId);
|
|
96
|
-
// => Date object
|
|
97
|
-
|
|
98
|
-
// Extract worker ID
|
|
99
|
-
const workerId = generator.extractWorkerId(snowflakeId);
|
|
100
|
-
// => 199
|
|
101
|
-
|
|
102
|
-
// Extract sequence
|
|
103
|
-
const sequence = generator.extractSequence(snowflakeId);
|
|
104
|
-
// => 0-4095
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Configuration
|
|
108
|
-
|
|
109
|
-
### SnowflakeConfig Constants
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
import { SnowflakeConfig } from '@venizia/ignis-helpers';
|
|
113
|
-
|
|
114
|
-
SnowflakeConfig.DEFAULT_EPOCH // BigInt(1735689600000) - 2025-01-01 00:00:00 UTC
|
|
115
|
-
SnowflakeConfig.MAX_WORKER_ID // 1023n
|
|
116
|
-
SnowflakeConfig.MAX_SEQUENCE // 4095n
|
|
117
|
-
SnowflakeConfig.TIMESTAMP_SHIFT // 22n
|
|
118
|
-
SnowflakeConfig.WORKER_ID_SHIFT // 12n
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Constructor Options
|
|
122
|
-
|
|
123
|
-
| Option | Type | Default | Description |
|
|
124
|
-
|--------|------|---------|-------------|
|
|
125
|
-
| `workerId` | `number` | `199` | Worker ID (0-1023) |
|
|
126
|
-
| `epoch` | `bigint` | `SnowflakeConfig.DEFAULT_EPOCH` | Custom epoch timestamp in milliseconds |
|
|
127
|
-
|
|
128
|
-
## Error Handling
|
|
129
|
-
|
|
130
|
-
The helper throws errors in these cases:
|
|
131
|
-
|
|
132
|
-
- **Invalid Worker ID**: Worker ID outside 0-1023 range
|
|
133
|
-
- **Invalid Epoch**: Epoch is zero, negative, or in the future
|
|
134
|
-
- **Clock Backward**: System clock moved backward by more than 100ms
|
|
135
|
-
- **Invalid Base62**: Decoding a string with invalid characters
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
try {
|
|
139
|
-
const generator = new SnowflakeUidHelper({ workerId: 2000 }); // Invalid
|
|
140
|
-
} catch (error) {
|
|
141
|
-
// Worker ID must be between 0 and 1023
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Best Practices
|
|
146
|
-
|
|
147
|
-
1. **Use unique worker IDs** in distributed systems to prevent ID collisions
|
|
148
|
-
2. **Keep epoch consistent** across all instances to ensure proper ID ordering
|
|
149
|
-
3. **Use `nextId()`** for most cases (returns compact Base62 string)
|
|
150
|
-
4. **Use `nextSnowflake()`** when you need the raw bigint for arithmetic operations
|
|
151
|
-
|
|
152
|
-
## See Also
|
|
153
|
-
|
|
154
|
-
- **Related Concepts:**
|
|
155
|
-
- [Models](/guides/core-concepts/persistent/models) - Using UIDs as primary keys
|
|
156
|
-
- [Services](/guides/core-concepts/services) - Generating unique IDs
|
|
157
|
-
|
|
158
|
-
- **Other Helpers:**
|
|
159
|
-
- [Helpers Index](./index) - All available helpers
|
|
160
|
-
- [Crypto Helper](./crypto) - For cryptographic random values
|
|
161
|
-
|
|
162
|
-
- **External Resources:**
|
|
163
|
-
- [Snowflake ID](https://en.wikipedia.org/wiki/Snowflake_ID) - Snowflake algorithm explained
|
|
164
|
-
- [Base62 Encoding](https://en.wikipedia.org/wiki/Base62) - Base62 encoding overview
|
|
165
|
-
|
|
166
|
-
- **Best Practices:**
|
|
167
|
-
- [Data Modeling](/best-practices/data-modeling) - ID generation strategies
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
# Worker Thread Helper
|
|
2
|
-
|
|
3
|
-
Manage Node.js `worker_threads` for concurrent CPU-bound task execution.
|
|
4
|
-
|
|
5
|
-
## Quick Reference
|
|
6
|
-
|
|
7
|
-
| Helper | Purpose |
|
|
8
|
-
|--------|---------|
|
|
9
|
-
| **WorkerPoolHelper** | Singleton managing pool of workers (matches CPU cores) |
|
|
10
|
-
| **BaseWorkerHelper** | Create and manage single worker thread lifecycle |
|
|
11
|
-
| **BaseWorkerBusHelper** | Two-way communication via `MessagePort` |
|
|
12
|
-
|
|
13
|
-
### Use Cases
|
|
14
|
-
|
|
15
|
-
- CPU-intensive calculations
|
|
16
|
-
- Large data processing
|
|
17
|
-
- Parallel computations
|
|
18
|
-
- Video/image processing
|
|
19
|
-
|
|
20
|
-
### Worker Communication
|
|
21
|
-
|
|
22
|
-
| Pattern | Complexity | Use When |
|
|
23
|
-
|---------|------------|----------|
|
|
24
|
-
| **Simple (parentPort)** | Low | One-way or basic messaging |
|
|
25
|
-
| **WorkerBus (MessageChannel)** | High | Complex two-way communication |
|
|
26
|
-
|
|
27
|
-
### WorkerPoolHelper Methods
|
|
28
|
-
|
|
29
|
-
| Method | Purpose |
|
|
30
|
-
|--------|---------|
|
|
31
|
-
| `getInstance()` | Get singleton instance |
|
|
32
|
-
| `register({ key, worker })` | Add worker to pool |
|
|
33
|
-
| `unregister({ key })` | Remove and terminate worker |
|
|
34
|
-
|
|
35
|
-
## `WorkerPoolHelper`
|
|
36
|
-
|
|
37
|
-
The `WorkerPoolHelper` is a singleton that manages the creation, registration, and termination of worker threads.
|
|
38
|
-
|
|
39
|
-
### Usage
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
import { WorkerPoolHelper, BaseWorkerHelper } from '@venizia/ignis';
|
|
43
|
-
|
|
44
|
-
const workerPool = WorkerPoolHelper.getInstance();
|
|
45
|
-
|
|
46
|
-
// Create a new worker
|
|
47
|
-
const myWorker = new BaseWorkerHelper({
|
|
48
|
-
identifier: 'my-cpu-intensive-task',
|
|
49
|
-
path: './path/to/my-worker.js',
|
|
50
|
-
options: {
|
|
51
|
-
workerData: { some: 'data' },
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// Register the worker with the pool
|
|
56
|
-
workerPool.register({ key: 'my-worker-1', worker: myWorker });
|
|
57
|
-
|
|
58
|
-
// Later, to terminate the worker
|
|
59
|
-
workerPool.unregister({ key: 'my-worker-1' });
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Creating a Worker
|
|
63
|
-
|
|
64
|
-
You can create a worker from the main thread that executes a separate script file.
|
|
65
|
-
|
|
66
|
-
### Main Thread (`main.ts`)
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
import { BaseWorkerHelper } from '@venizia/ignis';
|
|
70
|
-
import path from 'node:path';
|
|
71
|
-
|
|
72
|
-
const worker = new BaseWorkerHelper({
|
|
73
|
-
identifier: 'my-worker',
|
|
74
|
-
path: path.resolve(__dirname, './worker.ts'), // Path to the worker script
|
|
75
|
-
options: {
|
|
76
|
-
workerData: { message: 'Hello from main thread!' },
|
|
77
|
-
},
|
|
78
|
-
eventHandlers: {
|
|
79
|
-
onMessage: ({ message }) => {
|
|
80
|
-
console.log('Received message from worker:', message);
|
|
81
|
-
},
|
|
82
|
-
onError: ({ error }) => {
|
|
83
|
-
console.error('Worker error:', error);
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Worker Thread (`worker.ts`)
|
|
90
|
-
|
|
91
|
-
Inside the worker script, you can perform CPU-intensive tasks and communicate back to the main thread.
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
import { parentPort, workerData } from 'node:worker_threads';
|
|
95
|
-
|
|
96
|
-
console.log('Worker started with data:', workerData);
|
|
97
|
-
|
|
98
|
-
// Perform a CPU-intensive task
|
|
99
|
-
const result = performHeavyCalculation();
|
|
100
|
-
|
|
101
|
-
// Send the result back to the main thread
|
|
102
|
-
parentPort?.postMessage({ result });
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## `WorkerBus` for Two-Way Communication
|
|
106
|
-
|
|
107
|
-
For more complex scenarios requiring two-way communication, you can use the `WorkerBus` helpers.
|
|
108
|
-
|
|
109
|
-
### Main Thread (`main.ts`)
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
// ... (in main thread)
|
|
113
|
-
import { MessageChannel } from 'node:worker_threads';
|
|
114
|
-
import { BaseWorkerBusHelper, ... } from '@venizia/ignis';
|
|
115
|
-
|
|
116
|
-
const { port1, port2 } = new MessageChannel();
|
|
117
|
-
|
|
118
|
-
const worker = new BaseWorkerHelper({
|
|
119
|
-
// ...
|
|
120
|
-
options: {
|
|
121
|
-
workerData: { port: port2 }, // Pass one port to the worker
|
|
122
|
-
transferList: [port2], // Transfer ownership of the port
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
const mainThreadBus = new BaseWorkerBusHelper({
|
|
127
|
-
scope: 'main-bus',
|
|
128
|
-
port: port1,
|
|
129
|
-
busHandler: new BaseWorkerMessageBusHandlerHelper({
|
|
130
|
-
scope: 'main-bus-handler',
|
|
131
|
-
onMessage: ({ message }) => {
|
|
132
|
-
console.log('Main thread received:', message);
|
|
133
|
-
},
|
|
134
|
-
}),
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
mainThreadBus.postMessage({ message: { command: 'start-work' } });
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Worker Thread (`worker.ts`)
|
|
141
|
-
|
|
142
|
-
```typescript
|
|
143
|
-
// ... (in worker thread)
|
|
144
|
-
import { workerData } from 'node:worker_threads';
|
|
145
|
-
import { BaseWorkerBusHelper, ... } from '@venizia/ignis';
|
|
146
|
-
|
|
147
|
-
const { port } = workerData;
|
|
148
|
-
|
|
149
|
-
const workerBus = new BaseWorkerBusHelper({
|
|
150
|
-
scope: 'worker-bus',
|
|
151
|
-
port: port,
|
|
152
|
-
busHandler: new BaseWorkerMessageBusHandlerHelper({
|
|
153
|
-
scope: 'worker-bus-handler',
|
|
154
|
-
onMessage: ({ message }) => {
|
|
155
|
-
console.log('Worker received:', message);
|
|
156
|
-
if (message.command === 'start-work') {
|
|
157
|
-
workerBus.postMessage({ message: { status: 'work-done' } });
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
}),
|
|
161
|
-
});
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## See Also
|
|
165
|
-
|
|
166
|
-
- **Related Concepts:**
|
|
167
|
-
- [Services](/guides/core-concepts/services) - CPU-intensive tasks in services
|
|
168
|
-
|
|
169
|
-
- **Other Helpers:**
|
|
170
|
-
- [Helpers Index](./index) - All available helpers
|
|
171
|
-
- [Queue Helper](./queue) - For I/O-bound background tasks
|
|
172
|
-
|
|
173
|
-
- **External Resources:**
|
|
174
|
-
- [Node.js Worker Threads](https://nodejs.org/api/worker_threads.html) - Official worker_threads API
|
|
175
|
-
- [MessageChannel](https://nodejs.org/api/worker_threads.html#class-messagechannel) - Two-way communication
|
|
176
|
-
|
|
177
|
-
- **Best Practices:**
|
|
178
|
-
- [Performance Optimization](/best-practices/performance-optimization) - Worker thread strategies
|