{"_id":"@15ms/shikiid","_rev":"2-79e28d47445c581bfbe80eae7813e12c","name":"@15ms/shikiid","dist-tags":{"latest":"1.0.0"},"versions":{"0.1.0":{"name":"@15ms/shikiid","version":"0.1.0","keywords":["15ms","id","entity-id","base36"],"author":{"url":"https://sartrey.cn","name":"Sartrey Lee","email":"sartrey@163.com"},"license":"MIT","_id":"@15ms/shikiid@0.1.0","maintainers":[{"name":"sartrey","email":"sartrey@163.com"}],"homepage":"https://github.com/15ms/shikiid#readme","bugs":{"url":"https://github.com/15ms/shikiid/issues"},"bin":{"shikiid":"build/cli.js"},"dist":{"shasum":"ed80cac1d99bd87adc5cd50c1a381ba0eb405ac8","tarball":"https://registry.npmjs.org/@15ms/shikiid/-/shikiid-0.1.0.tgz","fileCount":9,"integrity":"sha512-lLJ99RoMkIXpdrO2zlOg7/u9WP4y0mZnQAxTtbbBZdDxEVzFJM52DIqN0G7DXaoxmYjJPIe0J8WHxsfORIB38g==","signatures":[{"sig":"MEYCIQC1yxoME9KzTg9AUSqL+W+K+pXZEfcYs2IAYzICDpcJIwIhAJca9DGtukMF4xblglDA75R+9RKUUP7wOnDRLpUd6bPM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":11730},"main":"build/index.js","type":"module","types":"./build/index.d.ts","engines":{"node":">=20.0.0"},"exports":"./build/index.js","gitHead":"f6e964caa59b041cb96407061a9f6b3f05281ba6","scripts":{"test":"npm run build && vitest run --coverage","build":"npm run clean && eslint . && tsc","clean":"rm -rf build && rm -rf coverage"},"_npmUser":{"name":"sartrey","email":"sartrey@163.com"},"repository":{"url":"git+https://github.com/15ms/shikiid.git","type":"git"},"_npmVersion":"11.9.0","description":"A compact parameterized identifier encoder.","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.25.1","vitest":"^3.2.4","typescript":"^5.8.0","@types/node":"^20.19.0","@vitest/coverage-v8":"^3.2.4","@epiijs/eslint-config":"^1.1.0"},"_npmOperationalInternal":{"tmp":"tmp/shikiid_0.1.0_1785669977750_0.27853637743187276","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@15ms/shikiid","version":"1.0.0","description":"A compact self-describing identifier encoder.","engines":{"node":">=20.0.0"},"type":"module","main":"build/index.js","exports":"./build/index.js","bin":{"shikiid":"build/shell.js"},"scripts":{"clean":"rm -rf build && rm -rf coverage","build":"npm run clean && eslint . && tsc","test":"npm run build && vitest run --coverage"},"repository":{"type":"git","url":"git+https://github.com/15ms/shikiid.git"},"keywords":["15ms","id","entity-id","base36"],"author":{"name":"Sartrey Lee","email":"sartrey@163.com","url":"https://sartrey.cn"},"license":"MIT","bugs":{"url":"https://github.com/15ms/shikiid/issues"},"homepage":"https://github.com/15ms/shikiid#readme","devDependencies":{"@epiijs/eslint-config":"^1.1.0","@types/node":"^20.19.0","@vitest/coverage-v8":"^3.2.4","eslint":"^9.25.1","typescript":"^5.8.0","vitest":"^3.2.4"},"gitHead":"0f4ffc828fde77281480cc95851c3aeaf6e22fec","types":"./build/index.d.ts","_id":"@15ms/shikiid@1.0.0","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-ys/h9OGeBF6QWclXdfjQSIMUY2LoFWCqBfoJjhxuh7mw3KwcYuqUhAnjf8B/Apk3NaHs6p53YTxz8/8209J0wQ==","shasum":"58e013d9aa134c5d298141bf61229e718e02d458","tarball":"https://registry.npmjs.org/@15ms/shikiid/-/shikiid-1.0.0.tgz","fileCount":13,"unpackedSize":18584,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICi7FYGzl4gWrwLSpTV9ST2K5dU5xvC0RRPtY5Jpl5iqAiEA8wgwUexi5nJwnIw1JBg2Eo48XVxHBa8XsR2LWy8ZP20="}]},"_npmUser":{"name":"sartrey","email":"sartrey@163.com"},"directories":{},"maintainers":[{"name":"sartrey","email":"sartrey@163.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/shikiid_1.0.0_1786891188926_0.24713840474953774"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-02T11:26:17.564Z","modified":"2026-08-16T14:39:49.232Z","0.1.0":"2026-08-02T11:26:17.878Z","1.0.0":"2026-08-16T14:39:49.066Z"},"bugs":{"url":"https://github.com/15ms/shikiid/issues"},"author":{"name":"Sartrey Lee","email":"sartrey@163.com","url":"https://sartrey.cn"},"license":"MIT","homepage":"https://github.com/15ms/shikiid#readme","keywords":["15ms","id","entity-id","base36"],"repository":{"type":"git","url":"git+https://github.com/15ms/shikiid.git"},"description":"A compact self-describing identifier encoder.","maintainers":[{"name":"sartrey","email":"sartrey@163.com"}],"readme":"# @15ms/shikiid\n\n紧凑的自描述标识编码器：2 位结构格式 + 时间前缀 + 随机片段。\n\n## 特性\n\n1. **强唯一性**，追求成本平衡的低碰撞概率，概率唯一即可\n2. **时间有序**，前缀编码创建时间，DB 索引聚簇友好，支持按时间范围查询（同一结构格式内成立）\n3. **自描述性**，头部 2 位结构格式 f 由编码参数与纪元号可计算得出，解析方无需外部配置即可拆解；编码结构和纪元轮转可无损演进\n4. **架构无关**，无状态，不引入中心化服务或节点注册\n5. **符号友好**，大小写不敏感，零特殊符号，base36 字符集\n6. **容量紧凑**，≤ 20 位，适配 `varchar(20)` DDL\n7. **业务无关**，纯标识符，不携带实体类型、租户等信息\n\n## 快速开始\n\n```ts\nimport { buildIdFormat, IdGenerator } from '@15ms/shikiid';\n\n// (tLevel, cLevel, bLevel, epochIndex, parity) → 2 位格式 f\nconst format = buildIdFormat({ tLevel: 0, cLevel: 0, bLevel: 2, epochIndex: 0 });\n\nconst generator = new IdGenerator(format, { rSize: 4 });\n\ngenerator.create();    // \"400ayx00x7k2\"   有序样式（系统内部）\ngenerator.create();    // \"400ayx01m3p9\"\ngenerator.decode(id);  // { t: '0ayx', c: '00', r: 'x7k2' }\n```\n\n生成器直接消费 f 字符串；`rSize` 缺省取容量上限（总长 20 封顶）。\n\n## ID 结构\n\n```\n{ 结构格式 f, 2 位 }{ 时间编码 t 位 }{ 自增轮转 c 位 }{ 随机片段 r 位 }\n```\n\n| 段 | 说明 |\n|----|------|\n| f | 由档位与纪元号打包的 2 位 base36，自描述 |\n| t | 桶编码的创建时间（tLevel 0~2 → 4~6 位） |\n| c | 进程内自增轮转（cLevel 0~1 → 2~3 位） |\n| r | 密码学安全随机后缀（4~14 位，不进 f） |\n\n### 档位参数\n\n| 参数 | 取值 | 说明 |\n|------|------|------|\n| `tLevel` | 0~2 | 时间编码档位（4~6 位） |\n| `cLevel` | 0~1 | 自增轮转档位（2~3 位） |\n| `bLevel` | 0~2 | 桶距档位：15 秒 / 5 分钟 / 1 小时 |\n| `epochIndex` | 0~35 | 纪元序号，0 号内置默认 2025-01-01 |\n| `parity` | 0~1 | 0 有序样式，1 无序样式 |\n\n### 预设配置\n\n| 配置 (t,c,b,e) | f | 桶距 | 寿命（t 位） | 总长 |\n|----------------|-----|------|--------------|------|\n| (0,0,2,0) | 40 | 1 小时 | ≈ 191 年（4 位） | 12 |\n| (0,0,1,0) | 20 | 5 分钟 | ≈ 16 年（4 位） | 12 |\n| (1,0,0,0) | c0 | 15 秒 | ≈ 29 年（5 位） | 15 |\n\n## 纪元与轮转\n\n```ts\nimport { indexOfEpoch } from '@15ms/shikiid';\n\nconst epochs = [Date.UTC(2030, 0, 1)];               // 自定义纪元须晚于默认纪元，自序号 1 起\nconst generator = new IdGenerator(format, { epochs }); // 0 号内置默认，无需登记\n\nindexOfEpoch(epochs, Date.now());                    // 最新的 ≤ now 纪元序号，全都晚于则 -1\n```\n\n寿命临近回绕时登记新纪元并切换生成器：新 f 自动不同，跨纪元 ID 永不碰撞，旧纪元 ID 仍可自解析。\n\n## 无序样式（用户可见展示）\n\n面向用户展示 ID 时用 `parity: 1`：段序反转为 `{f}{r}{c}{t}`，随机片段成为视觉主体，同时段创建的 ID 可区分；解析方读 f 得 p = 1 即可机械还原，零额外存储。\n\n```ts\nconst displayFormat = buildIdFormat({ tLevel: 0, cLevel: 0, bLevel: 2, epochIndex: 0, parity: 1 });\nnew IdGenerator(displayFormat, { rSize: 4 }).create();   // \"41x2k700xya0\"\n```\n\n## 碰撞率\n\n以 (0,0,2,0)、1 小时桶距、1296 个轮转分组为例：\n\n| 每桶 ID 数 | 碰撞率 |\n|-----------|--------|\n| 1,000 | ~10⁻⁷ |\n| 10,000 | ~0.002% |\n| 100,000 | ~0.18% |\n\n## 文档\n\n- [architecture.md](docs/architecture.md)：架构设计（权威来源）\n- [interface.md](docs/interface.md)：API 设计\n- [development.md](docs/development.md)：开发手册\n","readmeFilename":"README.md"}