@cdlab996/genid 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
  - 🔄 **时钟回拨处理**:优雅处理时钟回拨,不阻塞 ID 生成
9
9
  - ⚙️ **灵活配置**:支持自定义位长度分配
10
10
  - 📊 **性能监控**:内置统计和调试功能
11
+ - ✅ **ID 验证**:验证 ID 的有效性,支持严格/宽松模式
11
12
 
12
13
  ## 架构设计
13
14
 
@@ -153,6 +154,46 @@ console.log(info)
153
154
  // }
154
155
  ```
155
156
 
157
+ ### 验证 ID
158
+
159
+ #### `isValid(id, strictWorkerId?)`
160
+
161
+ 验证 ID 是否为有效的 Snowflake ID
162
+
163
+ **参数**
164
+ - `id` - 要验证的 ID(支持 Number、BigInt、String 类型)
165
+ - `strictWorkerId` - 可选,是否严格验证 workerId 必须匹配当前实例(默认:false)
166
+
167
+ **返回值**
168
+ - `boolean` - ID 是否有效
169
+
170
+ **验证规则**
171
+ - ✅ ID 为正数
172
+ - ✅ ID 在 64 位范围内
173
+ - ✅ 时间戳在合理范围内(>= baseTime,<= 当前时间 + 1秒容差)
174
+ - ✅ workerId 在有效范围内(0 到 2^workerIdBitLength-1)
175
+ - ✅ 序列号在有效范围内(0 到 2^seqBitLength-1)
176
+ - ✅ 严格模式下:workerId 必须匹配当前实例
177
+
178
+ ```typescript
179
+ const genid = new GenidOptimized({ workerId: 1 })
180
+ const id = genid.nextId()
181
+
182
+ // 宽松模式:验证 ID 格式是否有效
183
+ genid.isValid(id) // true
184
+ genid.isValid(12345) // false(无效的 ID)
185
+ genid.isValid(-1) // false(负数)
186
+ genid.isValid('invalid') // false(无效格式)
187
+
188
+ // 严格模式:验证 ID 是否由当前实例生成
189
+ const genid2 = new GenidOptimized({ workerId: 2 })
190
+ const id2 = genid2.nextId()
191
+
192
+ genid.isValid(id2) // true(宽松模式,其他实例的 ID 也有效)
193
+ genid.isValid(id2, true) // false(严格模式,workerId 不匹配)
194
+ genid.isValid(id, true) // true(严格模式,workerId 匹配)
195
+ ```
196
+
156
197
  ### 统计与配置
157
198
 
158
199
  #### `getStats()`
@@ -242,6 +283,30 @@ const genid = new GenidOptimized({
242
283
  })
243
284
  ```
244
285
 
286
+ ### 验证 ID
287
+
288
+ ```typescript
289
+ const genid = new GenidOptimized({ workerId: 1 })
290
+
291
+ // 生成并验证 ID
292
+ const id = genid.nextId()
293
+ if (genid.isValid(id)) {
294
+ console.log('ID 有效')
295
+ }
296
+
297
+ // 验证外部 ID(例如从数据库或 API 获取的 ID)
298
+ const externalId = '123456789012345'
299
+ if (genid.isValid(externalId)) {
300
+ const info = genid.parse(externalId)
301
+ console.log('ID 有效,解析结果:', info)
302
+ } else {
303
+ console.error('ID 无效')
304
+ }
305
+
306
+ // 严格验证(只接受当前实例生成的 ID)
307
+ const isMyId = genid.isValid(id, true)
308
+ ```
309
+
245
310
  ### 监控性能
246
311
 
247
312
  ```typescript
package/dist/index.cjs CHANGED
@@ -1,14 +1,15 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1
2
 
2
3
  //#region src/types/index.ts
3
4
  /**
4
5
  * ID 生成算法类型
5
6
  */
6
- let GenidMethod = /* @__PURE__ */ function(GenidMethod$1) {
7
+ let GenidMethod = /* @__PURE__ */ function(GenidMethod) {
7
8
  /** 漂移算法(推荐用于高性能场景) */
8
- GenidMethod$1[GenidMethod$1["DRIFT"] = 1] = "DRIFT";
9
+ GenidMethod[GenidMethod["DRIFT"] = 1] = "DRIFT";
9
10
  /** 传统算法 */
10
- GenidMethod$1[GenidMethod$1["TRADITIONAL"] = 2] = "TRADITIONAL";
11
- return GenidMethod$1;
11
+ GenidMethod[GenidMethod["TRADITIONAL"] = 2] = "TRADITIONAL";
12
+ return GenidMethod;
12
13
  }({});
13
14
 
14
15
  //#endregion
@@ -443,6 +444,41 @@ var GenidOptimized = class {
443
444
  };
444
445
  }
445
446
  /**
447
+ * 验证 ID 是否为有效的 Snowflake ID
448
+ *
449
+ * @param {number|bigint|string} id - 要验证的 ID
450
+ * @param {boolean} [strictWorkerId=false] - 是否严格验证 workerId 必须匹配当前实例
451
+ * @returns {boolean} ID 是否有效
452
+ *
453
+ * @example
454
+ * const genid = new GenidOptimized({ workerId: 1 });
455
+ * const id = genid.nextId();
456
+ * genid.isValid(id); // true
457
+ * genid.isValid(12345); // false
458
+ * genid.isValid(id, true); // true (workerId 匹配)
459
+ */
460
+ isValid(id, strictWorkerId = false) {
461
+ try {
462
+ const idBigInt = BigInt(id);
463
+ if (idBigInt < 0n) return false;
464
+ if (idBigInt >= 18446744073709551616n) return false;
465
+ const timestamp = (idBigInt >> this._timestampShift) + this.baseTime;
466
+ const workerIdMask = (1n << this.workerIdBitLength) - 1n;
467
+ const workerId = idBigInt >> this.seqBitLength & workerIdMask;
468
+ const sequence = idBigInt & (1n << this.seqBitLength) - 1n;
469
+ if (timestamp < this.baseTime) return false;
470
+ if (timestamp > BigInt(Date.now()) + 1000n) return false;
471
+ const maxWorkerId = (1n << this.workerIdBitLength) - 1n;
472
+ if (workerId < 0n || workerId > maxWorkerId) return false;
473
+ if (strictWorkerId && workerId !== this.workerId) return false;
474
+ const maxSeq = (1n << this.seqBitLength) - 1n;
475
+ if (sequence < 0n || sequence > maxSeq) return false;
476
+ return true;
477
+ } catch {
478
+ return false;
479
+ }
480
+ }
481
+ /**
446
482
  * 将 ID 格式化为二进制字符串以便调试
447
483
  *
448
484
  * @param {number|bigint|string} id - 要格式化的 ID
package/dist/index.d.cts CHANGED
@@ -6,7 +6,7 @@ declare enum GenidMethod {
6
6
  /** 漂移算法(推荐用于高性能场景) */
7
7
  DRIFT = 1,
8
8
  /** 传统算法 */
9
- TRADITIONAL = 2,
9
+ TRADITIONAL = 2
10
10
  }
11
11
  /**
12
12
  * ID 生成器配置选项
@@ -304,6 +304,21 @@ declare class GenidOptimized {
304
304
  * @returns {Object} 配置详情
305
305
  */
306
306
  getConfig(): ConfigResult;
307
+ /**
308
+ * 验证 ID 是否为有效的 Snowflake ID
309
+ *
310
+ * @param {number|bigint|string} id - 要验证的 ID
311
+ * @param {boolean} [strictWorkerId=false] - 是否严格验证 workerId 必须匹配当前实例
312
+ * @returns {boolean} ID 是否有效
313
+ *
314
+ * @example
315
+ * const genid = new GenidOptimized({ workerId: 1 });
316
+ * const id = genid.nextId();
317
+ * genid.isValid(id); // true
318
+ * genid.isValid(12345); // false
319
+ * genid.isValid(id, true); // true (workerId 匹配)
320
+ */
321
+ isValid(id: number | bigint | string, strictWorkerId?: boolean): boolean;
307
322
  /**
308
323
  * 将 ID 格式化为二进制字符串以便调试
309
324
  *
@@ -6,7 +6,7 @@ declare enum GenidMethod {
6
6
  /** 漂移算法(推荐用于高性能场景) */
7
7
  DRIFT = 1,
8
8
  /** 传统算法 */
9
- TRADITIONAL = 2,
9
+ TRADITIONAL = 2
10
10
  }
11
11
  /**
12
12
  * ID 生成器配置选项
@@ -304,6 +304,21 @@ declare class GenidOptimized {
304
304
  * @returns {Object} 配置详情
305
305
  */
306
306
  getConfig(): ConfigResult;
307
+ /**
308
+ * 验证 ID 是否为有效的 Snowflake ID
309
+ *
310
+ * @param {number|bigint|string} id - 要验证的 ID
311
+ * @param {boolean} [strictWorkerId=false] - 是否严格验证 workerId 必须匹配当前实例
312
+ * @returns {boolean} ID 是否有效
313
+ *
314
+ * @example
315
+ * const genid = new GenidOptimized({ workerId: 1 });
316
+ * const id = genid.nextId();
317
+ * genid.isValid(id); // true
318
+ * genid.isValid(12345); // false
319
+ * genid.isValid(id, true); // true (workerId 匹配)
320
+ */
321
+ isValid(id: number | bigint | string, strictWorkerId?: boolean): boolean;
307
322
  /**
308
323
  * 将 ID 格式化为二进制字符串以便调试
309
324
  *
@@ -2,12 +2,12 @@
2
2
  /**
3
3
  * ID 生成算法类型
4
4
  */
5
- let GenidMethod = /* @__PURE__ */ function(GenidMethod$1) {
5
+ let GenidMethod = /* @__PURE__ */ function(GenidMethod) {
6
6
  /** 漂移算法(推荐用于高性能场景) */
7
- GenidMethod$1[GenidMethod$1["DRIFT"] = 1] = "DRIFT";
7
+ GenidMethod[GenidMethod["DRIFT"] = 1] = "DRIFT";
8
8
  /** 传统算法 */
9
- GenidMethod$1[GenidMethod$1["TRADITIONAL"] = 2] = "TRADITIONAL";
10
- return GenidMethod$1;
9
+ GenidMethod[GenidMethod["TRADITIONAL"] = 2] = "TRADITIONAL";
10
+ return GenidMethod;
11
11
  }({});
12
12
 
13
13
  //#endregion
@@ -442,6 +442,41 @@ var GenidOptimized = class {
442
442
  };
443
443
  }
444
444
  /**
445
+ * 验证 ID 是否为有效的 Snowflake ID
446
+ *
447
+ * @param {number|bigint|string} id - 要验证的 ID
448
+ * @param {boolean} [strictWorkerId=false] - 是否严格验证 workerId 必须匹配当前实例
449
+ * @returns {boolean} ID 是否有效
450
+ *
451
+ * @example
452
+ * const genid = new GenidOptimized({ workerId: 1 });
453
+ * const id = genid.nextId();
454
+ * genid.isValid(id); // true
455
+ * genid.isValid(12345); // false
456
+ * genid.isValid(id, true); // true (workerId 匹配)
457
+ */
458
+ isValid(id, strictWorkerId = false) {
459
+ try {
460
+ const idBigInt = BigInt(id);
461
+ if (idBigInt < 0n) return false;
462
+ if (idBigInt >= 18446744073709551616n) return false;
463
+ const timestamp = (idBigInt >> this._timestampShift) + this.baseTime;
464
+ const workerIdMask = (1n << this.workerIdBitLength) - 1n;
465
+ const workerId = idBigInt >> this.seqBitLength & workerIdMask;
466
+ const sequence = idBigInt & (1n << this.seqBitLength) - 1n;
467
+ if (timestamp < this.baseTime) return false;
468
+ if (timestamp > BigInt(Date.now()) + 1000n) return false;
469
+ const maxWorkerId = (1n << this.workerIdBitLength) - 1n;
470
+ if (workerId < 0n || workerId > maxWorkerId) return false;
471
+ if (strictWorkerId && workerId !== this.workerId) return false;
472
+ const maxSeq = (1n << this.seqBitLength) - 1n;
473
+ if (sequence < 0n || sequence > maxSeq) return false;
474
+ return true;
475
+ } catch {
476
+ return false;
477
+ }
478
+ }
479
+ /**
445
480
  * 将 ID 格式化为二进制字符串以便调试
446
481
  *
447
482
  * @param {number|bigint|string} id - 要格式化的 ID
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cdlab996/genid",
3
3
  "type": "module",
4
- "version": "1.1.0",
4
+ "version": "1.2.1",
5
5
  "description": "基于 Snowflake 算法的高性能分布式唯一 ID 生成器",
6
6
  "author": "wudi <wuchendi96@gmail.com>",
7
7
  "license": "MIT",
@@ -30,14 +30,14 @@
30
30
  "default": "./dist/index.cjs"
31
31
  },
32
32
  "import": {
33
- "types": "./dist/index.d.ts",
34
- "default": "./dist/index.js"
33
+ "types": "./dist/index.d.mts",
34
+ "default": "./dist/index.mjs"
35
35
  }
36
36
  }
37
37
  },
38
- "main": "./dist/index.js",
39
- "module": "./dist/index.js",
40
- "types": "./dist/index.d.ts",
38
+ "main": "./dist/index.cjs",
39
+ "module": "./dist/index.mjs",
40
+ "types": "./dist/index.d.mts",
41
41
  "files": [
42
42
  "dist",
43
43
  "README.md",
@@ -47,10 +47,11 @@
47
47
  "node": ">=20"
48
48
  },
49
49
  "devDependencies": {
50
- "@types/node": "^24",
51
- "tsdown": "^0.15.9",
52
- "typescript": "^5.9.3",
53
- "vitest": "^4.0.2"
50
+ "@biomejs/biome": "^2.3.14",
51
+ "@types/node": "^25",
52
+ "tsdown": "^0.20.3",
53
+ "typescript": "^5",
54
+ "vitest": "^4.0.18"
54
55
  },
55
56
  "publishConfig": {
56
57
  "access": "public",
@@ -63,6 +64,9 @@
63
64
  "test:index": "vitest --run tests/index.test.ts",
64
65
  "test:performance": "vitest --run tests/performance.test.ts",
65
66
  "test:stress": "vitest --run tests/stress.test.ts",
67
+ "lint": "biome check",
68
+ "format": "biome format --write",
69
+ "clean": "bash ./scripts/clean.sh",
66
70
  "typecheck": "tsc --project tsconfig.json"
67
71
  }
68
72
  }