@venizia/ignis-docs 0.2.0 → 0.2.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +22 -11
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +26 -2
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +6 -2
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +182 -93
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +107 -322
- package/content/extensions/components/authentication/api.md +454 -603
- package/content/extensions/components/authentication/errors.md +121 -498
- package/content/extensions/components/authentication/index.md +88 -801
- package/content/extensions/components/authentication/usage.md +207 -956
- package/content/extensions/components/authorization/api.md +736 -656
- package/content/extensions/components/authorization/errors.md +168 -206
- package/content/extensions/components/authorization/index.md +82 -797
- package/content/extensions/components/authorization/usage.md +194 -527
- package/content/extensions/components/health-check.md +71 -243
- package/content/extensions/components/mail/api.md +504 -287
- package/content/extensions/components/mail/errors.md +73 -61
- package/content/extensions/components/mail/index.md +96 -467
- package/content/extensions/components/mail/usage.md +130 -172
- package/content/extensions/components/request-tracker.md +66 -173
- package/content/extensions/components/socket-io/api.md +195 -13
- package/content/extensions/components/socket-io/errors.md +3 -3
- package/content/extensions/components/socket-io/index.md +50 -337
- package/content/extensions/components/socket-io/usage.md +143 -26
- package/content/extensions/components/static-asset/api.md +410 -142
- package/content/extensions/components/static-asset/errors.md +110 -53
- package/content/extensions/components/static-asset/index.md +79 -608
- package/content/extensions/components/static-asset/usage.md +180 -300
- package/content/extensions/components/websocket/api.md +275 -399
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +74 -407
- package/content/extensions/components/websocket/usage.md +110 -341
- package/content/extensions/helpers/cron/index.md +51 -160
- package/content/extensions/helpers/crypto/index.md +62 -483
- package/content/extensions/helpers/crypto/reference.md +456 -0
- package/content/extensions/helpers/env/index.md +60 -178
- package/content/extensions/helpers/error/index.md +221 -207
- package/content/extensions/helpers/inversion/index.md +65 -556
- package/content/extensions/helpers/inversion/reference.md +522 -0
- package/content/extensions/helpers/kafka/admin.md +20 -1
- package/content/extensions/helpers/kafka/compile-binary.md +41 -35
- package/content/extensions/helpers/kafka/consumer.md +54 -20
- package/content/extensions/helpers/kafka/examples.md +21 -16
- package/content/extensions/helpers/kafka/index.md +80 -610
- package/content/extensions/helpers/kafka/producer.md +134 -5
- package/content/extensions/helpers/kafka/schema-registry.md +45 -70
- package/content/extensions/helpers/logger/hf-logger.md +193 -0
- package/content/extensions/helpers/logger/index.md +64 -563
- package/content/extensions/helpers/logger/pino.md +85 -0
- package/content/extensions/helpers/logger/reference.md +746 -0
- package/content/extensions/helpers/network/api.md +241 -195
- package/content/extensions/helpers/network/index.md +72 -530
- package/content/extensions/helpers/queue/index.md +72 -900
- package/content/extensions/helpers/queue/reference.md +467 -0
- package/content/extensions/helpers/redis/index.md +73 -645
- package/content/extensions/helpers/redis/reference.md +727 -0
- package/content/extensions/helpers/secrets/index.md +66 -0
- package/content/extensions/helpers/socket-io/api.md +305 -203
- package/content/extensions/helpers/socket-io/index.md +66 -432
- package/content/extensions/helpers/storage/api.md +564 -462
- package/content/extensions/helpers/storage/index.md +77 -573
- package/content/extensions/helpers/types/index.md +66 -499
- package/content/extensions/helpers/types/reference.md +650 -0
- package/content/extensions/helpers/uid/index.md +58 -227
- package/content/extensions/helpers/websocket/api.md +329 -216
- package/content/extensions/helpers/websocket/index.md +65 -503
- package/content/extensions/helpers/worker-thread/index.md +58 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/search-typesense.md +3 -3
- package/content/guides/core-concepts/persistent/transactions.md +1 -1
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/migrations/redis-helpers-migration.md +1 -1
- package/content/guides/migrations/unified-connectors-migration.md +2 -2
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/references/base/application.md +1 -1
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/datasources-reference.md +599 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +17 -39
- package/content/references/base/filter-system/application-usage.md +69 -121
- package/content/references/base/filter-system/array-operators.md +12 -0
- package/content/references/base/filter-system/comparison-operators.md +12 -0
- package/content/references/base/filter-system/default-filter.md +136 -348
- package/content/references/base/filter-system/fields-order-pagination.md +38 -16
- package/content/references/base/filter-system/index.md +106 -257
- package/content/references/base/filter-system/json-filtering.md +12 -2
- package/content/references/base/filter-system/list-operators.md +16 -2
- package/content/references/base/filter-system/logical-operators.md +13 -0
- package/content/references/base/filter-system/null-operators.md +13 -0
- package/content/references/base/filter-system/pattern-matching.md +12 -0
- package/content/references/base/filter-system/quick-reference.md +11 -2
- package/content/references/base/filter-system/range-operators.md +12 -0
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +156 -233
- package/content/references/base/middlewares.md +35 -21
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +80 -1452
- package/content/references/base/repositories/advanced.md +156 -192
- package/content/references/base/repositories/index.md +77 -650
- package/content/references/base/repositories/mixins.md +22 -18
- package/content/references/base/repositories/relations.md +123 -171
- package/content/references/base/repositories/soft-deletable.md +58 -56
- package/content/references/base/secrets.md +263 -0
- package/content/references/base/services.md +2 -2
- package/content/references/configuration/environment-variables.md +48 -4
- package/content/references/configuration/index.md +49 -31
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/index.md +1 -1
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +29 -62
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +57 -218
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/package.json +8 -8
|
@@ -1,272 +1,103 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Snowflake ID generator with Base62 encoding for unique, time-sortable distributed identifiers
|
|
1
|
+
---
|
|
2
|
+
title: UID
|
|
3
|
+
description: Snowflake ID generator with Base62 encoding for unique, time-sortable distributed identifiers
|
|
4
|
+
difficulty: beginner
|
|
5
|
+
---
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
# UID
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|------|-------|
|
|
9
|
-
| **Package** | `@venizia/ignis-helpers` |
|
|
10
|
-
| **Class** | `SnowflakeUidHelper` |
|
|
11
|
-
| **Extends** | `BaseHelper` |
|
|
12
|
-
| **Runtimes** | Both |
|
|
9
|
+
`SnowflakeUidHelper` generates 70-bit, time-sortable Snowflake IDs and encodes them as compact Base62 strings, suitable as database primary keys.
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
## In one example
|
|
15
12
|
|
|
16
13
|
```typescript
|
|
17
|
-
import { SnowflakeUidHelper
|
|
14
|
+
import { SnowflakeUidHelper } from '@venizia/ignis-helpers';
|
|
18
15
|
|
|
19
|
-
//
|
|
20
|
-
|
|
16
|
+
const generator = new SnowflakeUidHelper(); // workerId: 199, epoch: 2025-01-01 UTC
|
|
17
|
+
const id = generator.nextId();
|
|
18
|
+
// => e.g. "9du1sJXO88"
|
|
21
19
|
```
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
| Component | Bits | Range | Purpose |
|
|
26
|
-
|-----------|------|-------|---------|
|
|
27
|
-
| Timestamp | 48 | ~8,919 years | Time since epoch |
|
|
28
|
-
| Worker ID | 10 | 0--1023 | Unique worker identifier |
|
|
29
|
-
| Sequence | 12 | 0--4095 | IDs per millisecond |
|
|
30
|
-
|
|
31
|
-
#### Key Specifications
|
|
21
|
+
Use one `SnowflakeUidHelper` instance per worker process - `nextId()` returns a URL-safe Base62 string that sorts the same order as the IDs were generated.
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|------|-------|
|
|
35
|
-
| Base62 Output | 10--12 characters |
|
|
36
|
-
| Throughput | 4,096,000 IDs/second/worker |
|
|
37
|
-
| Max Workers | 1024 |
|
|
38
|
-
| Lifespan | Until ~10,944 AD |
|
|
39
|
-
| Default Epoch | 2025-01-01 00:00:00 UTC |
|
|
23
|
+
## How it works
|
|
40
24
|
|
|
41
|
-
|
|
25
|
+
- **The ID packs three fields into 70 bits.** A 48-bit timestamp (offset from a custom epoch), a 10-bit worker ID (0-1023), and a 12-bit sequence (0-4095) - shifted and OR'd together in `nextSnowflake()`. Sorting the raw bigints, or the Base62 strings, sorts by generation time.
|
|
26
|
+
- **The sequence resets every millisecond, per worker.** Within the same millisecond it increments and wraps at 4096; a wrap forces the generator to busy-wait for the next millisecond, capping throughput at 4,096,000 IDs/second/worker.
|
|
27
|
+
- **Backward clock drift is handled, up to a point.** A drift up to 100ms (`MAX_CLOCK_BACKWARD_MS`) busy-waits until the clock catches up, logging a warning. A larger drift throws instead of risking a duplicate ID.
|
|
28
|
+
- **`encodeBase62` / `decodeBase62` are just a bigint <-> string codec.** They do not know about the Snowflake layout - `parseId()` is `decodeBase62()` followed by the three `extract*` calls, all built on the same instance's `epoch` and bit-shift constants.
|
|
29
|
+
- **An expiry warning logs once the epoch nears its 48-bit limit.** ~8,919 years after the configured epoch the timestamp field overflows; a warning starts logging 10 years before that.
|
|
42
30
|
|
|
43
|
-
|
|
31
|
+
**Snowflake layout (70 bits)**
|
|
44
32
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// Or with custom values
|
|
52
|
-
const customGenerator = new SnowflakeUidHelper({
|
|
53
|
-
workerId: 123,
|
|
54
|
-
epoch: BigInt(1735689600000),
|
|
55
|
-
});
|
|
56
|
-
```
|
|
33
|
+
| Component | Bits | Range | Purpose |
|
|
34
|
+
|-----------|------|-------|---------|
|
|
35
|
+
| Timestamp | 48 | ~8,919 years | Milliseconds since `epoch` |
|
|
36
|
+
| Worker ID | 10 | 0-1023 | Set per instance, must be unique across a deployment |
|
|
37
|
+
| Sequence | 12 | 0-4095 | IDs generated within the same millisecond |
|
|
57
38
|
|
|
58
|
-
|
|
39
|
+
**`IIdGeneratorOptions`**
|
|
59
40
|
|
|
60
41
|
| Option | Type | Default | Description |
|
|
61
42
|
|--------|------|---------|-------------|
|
|
62
|
-
| `workerId` | `number` | `199` |
|
|
63
|
-
| `epoch` | `bigint` | `BigInt(1735689600000)`
|
|
64
|
-
|
|
65
|
-
> [!TIP]
|
|
66
|
-
> Use unique worker IDs in distributed systems to prevent ID collisions, and keep the epoch consistent across all instances to ensure proper ID ordering.
|
|
67
|
-
|
|
68
|
-
#### `SnowflakeConfig` Constants
|
|
43
|
+
| `workerId` | `number` | `199` | Integer, `0`-`1023` |
|
|
44
|
+
| `epoch` | `bigint` | `BigInt(1735689600000)` (2025-01-01 00:00:00 UTC) | Positive, must be in the past |
|
|
69
45
|
|
|
70
|
-
|
|
71
|
-
import { SnowflakeConfig } from '@venizia/ignis-helpers';
|
|
72
|
-
|
|
73
|
-
SnowflakeConfig.DEFAULT_EPOCH // BigInt(1735689600000) - 2025-01-01 00:00:00 UTC
|
|
74
|
-
SnowflakeConfig.MAX_WORKER_ID // 1023n
|
|
75
|
-
SnowflakeConfig.MAX_SEQUENCE // 4095n
|
|
76
|
-
SnowflakeConfig.TIMESTAMP_SHIFT // 22n
|
|
77
|
-
SnowflakeConfig.WORKER_ID_SHIFT // 12n
|
|
78
|
-
|
|
79
|
-
// Bit widths
|
|
80
|
-
SnowflakeConfig.TIMESTAMP_BITS // 48n
|
|
81
|
-
SnowflakeConfig.WORKER_ID_BITS // 10n
|
|
82
|
-
SnowflakeConfig.SEQUENCE_BITS // 12n
|
|
83
|
-
|
|
84
|
-
// Safety thresholds
|
|
85
|
-
SnowflakeConfig.MAX_CLOCK_BACKWARD_MS // 100n (busy-wait tolerance)
|
|
86
|
-
SnowflakeConfig.MAX_TIMESTAMP_MS // (1n << 48n) - 1n (~8,919 years)
|
|
87
|
-
SnowflakeConfig.WARNING_THRESHOLD_MS // ~8,909 years (warns 10 years before expiry)
|
|
88
|
-
```
|
|
46
|
+
## Common tasks
|
|
89
47
|
|
|
90
|
-
|
|
48
|
+
### Generate an ID
|
|
91
49
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
Generate unique Snowflake IDs as either compact Base62 strings or raw bigints.
|
|
50
|
+
`nextId()` is the common case - a Base62 string, 10-12 characters. `nextSnowflake()` returns the raw `bigint` when you need arithmetic or bit-level access.
|
|
95
51
|
|
|
96
52
|
```typescript
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
// => e.g., "9du1sJXO88"
|
|
100
|
-
|
|
101
|
-
// Generate raw Snowflake ID as bigint
|
|
102
|
-
const snowflakeId = generator.nextSnowflake();
|
|
103
|
-
// => e.g., 130546360012247045n
|
|
53
|
+
const id = generator.nextId(); // "9du1sJXO88"
|
|
54
|
+
const raw = generator.nextSnowflake(); // 130546360012247045n
|
|
104
55
|
```
|
|
105
56
|
|
|
106
|
-
|
|
107
|
-
> Use `nextId()` for most cases -- it returns a compact Base62 string (10--12 chars) that works well as database primary keys and URL-safe identifiers. Use `nextSnowflake()` only when you need the raw bigint for arithmetic or bit-level operations.
|
|
108
|
-
|
|
109
|
-
#### Clock Drift Handling
|
|
110
|
-
|
|
111
|
-
When `nextSnowflake()` detects the system clock has moved backward:
|
|
112
|
-
- Drifts up to 100ms are handled automatically by busy-waiting until the clock catches up.
|
|
113
|
-
- Drifts exceeding 100ms throw an error to protect ID uniqueness.
|
|
114
|
-
- A warning is logged whenever any backward clock movement is detected.
|
|
115
|
-
|
|
116
|
-
#### Sequence Exhaustion
|
|
117
|
-
|
|
118
|
-
If more than 4096 IDs are requested in a single millisecond from the same worker, the generator busy-waits until the next millisecond before continuing. This is transparent to the caller.
|
|
119
|
-
|
|
120
|
-
### Base62 Encoding and Decoding
|
|
121
|
-
|
|
122
|
-
Encode any bigint to a compact, URL-safe Base62 string using the alphabet `0-9A-Za-z`, or decode back to the original bigint.
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
// Encode
|
|
126
|
-
const encoded = generator.encodeBase62(130546360012247045n);
|
|
127
|
-
// => "9du1sJXO88"
|
|
128
|
-
|
|
129
|
-
// Decode
|
|
130
|
-
const decoded = generator.decodeBase62('9du1sJXO88');
|
|
131
|
-
// => 130546360012247045n
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
> [!WARNING]
|
|
135
|
-
> `decodeBase62()` throws if the input contains characters outside the Base62 alphabet (`0-9`, `A-Z`, `a-z`). Watch for URL-encoded strings or accidental whitespace.
|
|
136
|
-
|
|
137
|
-
### Parsing IDs
|
|
138
|
-
|
|
139
|
-
Extract the embedded timestamp, worker ID, and sequence from a generated ID.
|
|
140
|
-
|
|
141
|
-
#### Parse a Base62 ID
|
|
57
|
+
### Parse an ID back into its components
|
|
142
58
|
|
|
143
59
|
```typescript
|
|
144
60
|
const parsed = generator.parseId('9du1sJXO88');
|
|
145
|
-
// => {
|
|
146
|
-
// raw: 130546360012247045n,
|
|
147
|
-
// timestamp: Date,
|
|
148
|
-
// workerId: 199,
|
|
149
|
-
// sequence: 0
|
|
150
|
-
// }
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
#### `ISnowflakeParsedId`
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
interface ISnowflakeParsedId {
|
|
157
|
-
raw: bigint;
|
|
158
|
-
timestamp: Date;
|
|
159
|
-
workerId: number;
|
|
160
|
-
sequence: number;
|
|
161
|
-
}
|
|
61
|
+
// => { raw: 130546360012247045n, timestamp: Date, workerId: 199, sequence: 0 }
|
|
162
62
|
```
|
|
163
63
|
|
|
164
|
-
|
|
64
|
+
### Extract a single component from a raw ID
|
|
165
65
|
|
|
166
66
|
```typescript
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const timestamp = generator.extractTimestamp(snowflakeId);
|
|
171
|
-
// => Date object
|
|
172
|
-
|
|
173
|
-
// Extract worker ID
|
|
174
|
-
const workerId = generator.extractWorkerId(snowflakeId);
|
|
175
|
-
// => 199
|
|
176
|
-
|
|
177
|
-
// Extract sequence
|
|
178
|
-
const sequence = generator.extractSequence(snowflakeId);
|
|
179
|
-
// => 0-4095
|
|
180
|
-
|
|
181
|
-
// Get current instance's worker ID
|
|
182
|
-
const currentWorkerId = generator.getWorkerId();
|
|
183
|
-
// => 199
|
|
67
|
+
const timestamp = generator.extractTimestamp(raw);
|
|
68
|
+
const workerId = generator.extractWorkerId(raw);
|
|
69
|
+
const sequence = generator.extractSequence(raw);
|
|
184
70
|
```
|
|
185
71
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
| Method | Signature | Description |
|
|
189
|
-
|--------|-----------|-------------|
|
|
190
|
-
| `nextId` | `nextId(): string` | Generate a Base62-encoded Snowflake ID (10--12 chars) |
|
|
191
|
-
| `nextSnowflake` | `nextSnowflake(): bigint` | Generate a raw 70-bit Snowflake ID |
|
|
192
|
-
| `encodeBase62` | `encodeBase62(num: bigint): string` | Encode a bigint to Base62 string |
|
|
193
|
-
| `decodeBase62` | `decodeBase62(str: string): bigint` | Decode a Base62 string to bigint |
|
|
194
|
-
| `parseId` | `parseId(base62Id: string): ISnowflakeParsedId` | Parse a Base62 ID into its components |
|
|
195
|
-
| `extractTimestamp` | `extractTimestamp(id: bigint): Date` | Extract the timestamp from a raw Snowflake ID |
|
|
196
|
-
| `extractWorkerId` | `extractWorkerId(id: bigint): number` | Extract the worker ID from a raw Snowflake ID |
|
|
197
|
-
| `extractSequence` | `extractSequence(id: bigint): number` | Extract the sequence number from a raw Snowflake ID |
|
|
198
|
-
| `getWorkerId` | `getWorkerId(): number` | Get the current instance's worker ID |
|
|
72
|
+
### Run one generator per worker in a distributed deployment
|
|
199
73
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
### "Worker ID must be between 0 and 1023"
|
|
203
|
-
|
|
204
|
-
**Cause:** The `workerId` option passed to the constructor is negative or exceeds 1023 (10-bit maximum).
|
|
205
|
-
|
|
206
|
-
**Fix:** Ensure the worker ID is within the valid range (0--1023):
|
|
74
|
+
Give each process a unique `workerId`; keep `epoch` identical across all of them so ID ordering stays meaningful.
|
|
207
75
|
|
|
208
76
|
```typescript
|
|
209
|
-
|
|
210
|
-
new SnowflakeUidHelper({ workerId: 2000 });
|
|
211
|
-
|
|
212
|
-
// Correct
|
|
213
|
-
new SnowflakeUidHelper({ workerId: 1 });
|
|
77
|
+
const generator = new SnowflakeUidHelper({ workerId: Number(process.env.WORKER_ID) });
|
|
214
78
|
```
|
|
215
79
|
|
|
216
|
-
###
|
|
80
|
+
### Decode Base62 defensively
|
|
217
81
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
**Fix:** Provide a valid epoch as a positive bigint representing milliseconds since Unix epoch:
|
|
82
|
+
`decodeBase62()` throws on any character outside `0-9A-Za-z` - including a leading space or a URL-decoded `+`.
|
|
221
83
|
|
|
222
84
|
```typescript
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
//
|
|
227
|
-
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### "Epoch cannot be in the future"
|
|
231
|
-
|
|
232
|
-
**Cause:** The `epoch` option is set to a timestamp later than the current time. A future epoch would produce negative timestamp offsets in generated IDs.
|
|
233
|
-
|
|
234
|
-
**Fix:** Use a past date as the epoch. The default (`2025-01-01 00:00:00 UTC`) is recommended unless you have a specific reason to change it.
|
|
235
|
-
|
|
236
|
-
### "Clock moved backward by Xms. Refusing to generate ID."
|
|
237
|
-
|
|
238
|
-
**Cause:** The system clock moved backward by more than 100ms, typically caused by NTP time synchronization. Small drifts (up to 100ms) are handled by busy-waiting, but larger jumps are rejected to protect ID uniqueness.
|
|
239
|
-
|
|
240
|
-
**Fix:** Ensure your system clock is stable. If running in containers, verify the host clock is not being adjusted aggressively. There is no code-level workaround -- the error protects against duplicate IDs.
|
|
241
|
-
|
|
242
|
-
### "Invalid Base62 character: X"
|
|
243
|
-
|
|
244
|
-
**Cause:** `decodeBase62()` encountered a character outside the Base62 alphabet (`0-9`, `A-Z`, `a-z`).
|
|
245
|
-
|
|
246
|
-
**Fix:** Ensure the input string only contains valid Base62 characters:
|
|
247
|
-
|
|
248
|
-
```typescript
|
|
249
|
-
// Wrong
|
|
250
|
-
generator.decodeBase62('9du1sJ+O88'); // '+' is not Base62
|
|
251
|
-
generator.decodeBase62(' 9du1sJXO88'); // leading space
|
|
252
|
-
|
|
253
|
-
// Correct
|
|
254
|
-
generator.decodeBase62('9du1sJXO88');
|
|
85
|
+
try {
|
|
86
|
+
const raw = generator.decodeBase62(userSuppliedId);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
// not a valid Base62 ID
|
|
89
|
+
}
|
|
255
90
|
```
|
|
256
91
|
|
|
257
|
-
## See
|
|
258
|
-
|
|
259
|
-
- **Related Concepts:**
|
|
260
|
-
- [Models](/guides/core-concepts/persistent/models) - Using UIDs as primary keys
|
|
261
|
-
- [Services](/guides/core-concepts/services) - Generating unique IDs in services
|
|
92
|
+
## See also
|
|
262
93
|
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
|
|
94
|
+
- [Models](/guides/core-concepts/persistent/models) - using UIDs as primary keys
|
|
95
|
+
- [Services](/guides/core-concepts/services) - generating unique IDs in services
|
|
96
|
+
- [Helpers Overview](/extensions/helpers/) - all available helpers
|
|
97
|
+
- [Crypto Helper](/extensions/helpers/crypto/) - cryptographic random values
|
|
98
|
+
- [Snowflake ID](https://en.wikipedia.org/wiki/Snowflake_ID) - the algorithm this helper implements
|
|
266
99
|
|
|
267
|
-
|
|
268
|
-
- [Snowflake ID](https://en.wikipedia.org/wiki/Snowflake_ID) - Snowflake algorithm explained
|
|
269
|
-
- [Base62 Encoding](https://en.wikipedia.org/wiki/Base62) - Base62 encoding overview
|
|
100
|
+
**Files:**
|
|
270
101
|
|
|
271
|
-
-
|
|
272
|
-
|
|
102
|
+
- [`packages/helpers/src/modules/uid/helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/uid/helper.ts) - `SnowflakeUidHelper`, `SnowflakeConfig`
|
|
103
|
+
- [`packages/helpers/src/modules/uid/index.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/uid/index.ts) - module barrel
|