Buckets:
| import { randomBytes } from "crypto" | |
| const prefixes = { | |
| job: "job", | |
| event: "evt", | |
| session: "ses", | |
| message: "msg", | |
| permission: "per", | |
| question: "que", | |
| part: "prt", | |
| pty: "pty", | |
| tool: "tool", | |
| workspace: "wrk", | |
| } as const | |
| const LENGTH = 26 | |
| // State for monotonic ID generation | |
| let lastTimestamp = 0 | |
| let counter = 0 | |
| export function ascending(prefix: keyof typeof prefixes, given?: string) { | |
| return generateID(prefix, "ascending", given) | |
| } | |
| export function descending(prefix: keyof typeof prefixes, given?: string) { | |
| return generateID(prefix, "descending", given) | |
| } | |
| function generateID(prefix: keyof typeof prefixes, direction: "descending" | "ascending", given?: string): string { | |
| if (!given) { | |
| return create(prefixes[prefix], direction) | |
| } | |
| if (!given.startsWith(prefixes[prefix])) { | |
| throw new Error(`ID ${given} does not start with ${prefixes[prefix]}`) | |
| } | |
| return given | |
| } | |
| function randomBase62(length: number): string { | |
| const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | |
| let result = "" | |
| const bytes = randomBytes(length) | |
| for (let i = 0; i < length; i++) { | |
| result += chars[bytes[i] % 62] | |
| } | |
| return result | |
| } | |
| export function create(prefix: string, direction: "descending" | "ascending", timestamp?: number): string { | |
| const currentTimestamp = timestamp ?? Date.now() | |
| if (currentTimestamp !== lastTimestamp) { | |
| lastTimestamp = currentTimestamp | |
| counter = 0 | |
| } | |
| counter++ | |
| let now = BigInt(currentTimestamp) * BigInt(0x1000) + BigInt(counter) | |
| now = direction === "descending" ? ~now : now | |
| const timeBytes = Buffer.alloc(6) | |
| for (let i = 0; i < 6; i++) { | |
| timeBytes[i] = Number((now >> BigInt(40 - 8 * i)) & BigInt(0xff)) | |
| } | |
| return prefix + "_" + timeBytes.toString("hex") + randomBase62(LENGTH - 12) | |
| } | |
| /** Extract timestamp from an ascending ID. Does not work with descending IDs. */ | |
| export function timestamp(id: string): number { | |
| const prefix = id.split("_")[0] | |
| const hex = id.slice(prefix.length + 1, prefix.length + 13) | |
| const encoded = BigInt("0x" + hex) | |
| return Number(encoded / BigInt(0x1000)) | |
| } | |
| export * as Identifier from "./id" | |
Xet Storage Details
- Size:
- 2.16 kB
- Xet hash:
- 0a3d97930a07fc4b95df9dfacfb26ec7d9416e8ed178032b6ff74a3879454393
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.