import { randomBytes } from 'node:crypto'; /** * UUIDv7 — 48-bit Unix-ms timestamp in the high bits, 74 random bits below. * * Time-ordered, monotonic enough for our needs (idempotency keys + Stream IDs). * No dependency on the `uuid` package — Phase 0 keeps the foundation * tree-shakeable for the Python side (which uses its own implementation). * * Reference: RFC 9562 §5.7. */ export function uuidv7(now: number = Date.now()): string { const ts = BigInt(now); // milliseconds since epoch const bytes = randomBytes(16); // 48-bit timestamp (big-endian) in bytes 0..5 bytes[0] = Number((ts >> 40n) & 0xffn); bytes[1] = Number((ts >> 32n) & 0xffn); bytes[2] = Number((ts >> 24n) & 0xffn); bytes[3] = Number((ts >> 16n) & 0xffn); bytes[4] = Number((ts >> 8n) & 0xffn); bytes[5] = Number(ts & 0xffn); // Version 7 in the high nibble of byte 6 bytes[6] = (bytes[6]! & 0x0f) | 0x70; // RFC 4122 variant (10xx) in the high bits of byte 8 bytes[8] = (bytes[8]! & 0x3f) | 0x80; const hex = Buffer.from(bytes).toString('hex'); return [ hex.slice(0, 8), hex.slice(8, 12), hex.slice(12, 16), hex.slice(16, 20), hex.slice(20, 32), ].join('-'); } const UUID_V7_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; export function isUuidV7(value: string): boolean { return UUID_V7_RE.test(value); }