{"version":3,"file":"v7.mjs","names":["state: V7State","bytes: Uint8Array","uuidv7: UuidV7"],"sources":["../../src/uuid/v7.ts"],"sourcesContent":["import { rng } from '../common/random'\nimport { BufferError, InvalidInputError } from '../errors'\nimport { formatUuid, parseUuid } from './common/uuid'\n\nexport type UuidV7Options = {\n  /**\n   * 16 bytes of random data to use for UUID generation.\n   * Note: Several bytes will be overwritten with timestamp, version, and variant data.\n   */\n  random?: Uint8Array\n  msecs?: number\n  seq?: number\n}\n\nexport type UuidV7 = {\n  (): string\n  <TBuf extends Uint8Array = Uint8Array>(options: UuidV7Options | undefined, buf: TBuf, offset?: number): TBuf\n  (options?: UuidV7Options, buf?: undefined, offset?: number): string\n  toBytes(id: string): Uint8Array\n  fromBytes(bytes: Uint8Array): string\n  timestamp(id: string): number\n  isValid(id: unknown): id is string\n  /** The nil UUID (all zeros) */\n  NIL: string\n  /** The max UUID (all ones) */\n  MAX: string\n}\n\nconst UUID_V7_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\n// Reusable buffer for string output path - avoids allocation per call.\n// Safe because bytes are consumed synchronously by formatUuid().\nconst reusableBuf = new Uint8Array(16)\n\ntype V7State = {\n  msecs: number\n  seq: number\n}\n\n/**\n * Module-level state for maintaining monotonic ordering within the same millisecond.\n *\n * IMPORTANT: This state persists across all uuidv7() calls in the module's lifetime.\n * - In serverless/edge functions with warm starts, state persists between invocations.\n * - For isolated state, pass explicit `msecs` and `seq` via options.\n * - Tests should mock Date.now() or provide explicit options for deterministic behavior.\n */\nconst state: V7State = { msecs: -Infinity, seq: 0 }\n\nfunction v7Bytes(\n  rnds: Uint8Array,\n  msecs: number | undefined,\n  seq: number | undefined,\n  buf: Uint8Array,\n  offset = 0,\n): Uint8Array {\n  if (rnds.length < 16) {\n    throw new InvalidInputError('UUID_RANDOM_BYTES_TOO_SHORT', 'Random bytes length must be >= 16')\n  }\n\n  if (offset < 0 || offset + 16 > buf.length) {\n    throw new BufferError(\n      'UUID_BUFFER_OUT_OF_BOUNDS',\n      `UUID byte range ${offset}:${offset + 15} is out of buffer bounds`,\n    )\n  }\n\n  msecs ??= Date.now()\n  // Derive a 31-bit sequence if not provided by the caller.\n  // Uses same formula as hot path (line 130) for consistency.\n  seq ??= (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9]\n\n  // Timestamp (48-bit big-endian milliseconds since Unix epoch).\n  // byte 0-5: timestamp (48 bits)\n  buf[offset++] = (msecs / 0x10000000000) & 0xff\n  buf[offset++] = (msecs / 0x100000000) & 0xff\n  buf[offset++] = (msecs / 0x1000000) & 0xff\n  buf[offset++] = (msecs / 0x10000) & 0xff\n  buf[offset++] = (msecs / 0x100) & 0xff\n  buf[offset++] = msecs & 0xff\n\n  // Set version (7) and variant (10xx), then pack sequence and random tail bytes.\n  buf[offset++] = 0x70 | ((seq >>> 28) & 0x0f)\n  buf[offset++] = (seq >>> 20) & 0xff\n  buf[offset++] = 0x80 | ((seq >>> 14) & 0x3f)\n  buf[offset++] = (seq >>> 6) & 0xff\n  // Lower seq bits plus 2 random bits to complete the 128-bit payload.\n  buf[offset++] = ((seq << 2) & 0xff) | (rnds[10] & 0x03)\n  buf[offset++] = rnds[11]\n  buf[offset++] = rnds[12]\n  buf[offset++] = rnds[13]\n  buf[offset++] = rnds[14]\n  buf[offset++] = rnds[15]\n\n  return buf\n}\n\n/*\n * Overload: no buffer => return a UUID string.\n */\nfunction v7(options?: UuidV7Options, buf?: undefined, offset?: number): string\n/*\n * Overload: caller provides a buffer slice to fill with UUID bytes.\n */\nfunction v7<TBuf extends Uint8Array = Uint8Array>(options: UuidV7Options | undefined, buf: TBuf, offset?: number): TBuf\nfunction v7<TBuf extends Uint8Array = Uint8Array>(options?: UuidV7Options, buf?: TBuf, offset?: number): string | TBuf {\n  let bytes: Uint8Array\n\n  if (options) {\n    bytes = v7Bytes(options.random ?? rng(), options.msecs, options.seq, buf ?? reusableBuf, buf ? offset : 0)\n  } else {\n    // HOT PATH: Inline state management and byte generation for best performance\n    const now = Date.now()\n    const rnds = rng()\n\n    // Update state (inlined for performance)\n    if (now > state.msecs) {\n      state.seq = (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9]\n      state.msecs = now\n    } else {\n      state.seq = (state.seq + 1) | 0\n      if (state.seq === 0) {\n        state.msecs++\n      }\n    }\n\n    bytes = v7Bytes(rnds, state.msecs, state.seq, buf ?? reusableBuf, buf ? offset : 0)\n  }\n\n  return buf ? (bytes as TBuf) : formatUuid(bytes)\n}\n\nfunction timestamp(id: string): number {\n  const bytes = parseUuid(id)\n  let msecs = 0\n  for (let i = 0; i < 6; i += 1) {\n    msecs = msecs * 256 + bytes[i]\n  }\n  return msecs\n}\n\nfunction isValid(id: unknown): id is string {\n  return typeof id === 'string' && UUID_V7_REGEX.test(id)\n}\n\n/**\n * Generate a UUID v7 string or write the bytes into a buffer.\n *\n * UUID v7 is a time-ordered UUID that embeds a Unix timestamp in milliseconds,\n * making IDs naturally sortable by creation time. Ideal for database primary keys\n * where chronological ordering improves index performance.\n *\n * @example\n * ```ts\n * import { uuidv7 } from 'uniku/uuid/v7'\n *\n * const id = uuidv7()\n * // => \"018e5e5c-7c8a-7000-8000-000000000000\"\n *\n * // Extract timestamp\n * const ts = uuidv7.timestamp(id)\n * console.log(new Date(ts))\n *\n * // Validate\n * uuidv7.isValid(id) // true\n *\n * // Convert to/from bytes\n * const bytes = uuidv7.toBytes(id)\n * const restored = uuidv7.fromBytes(bytes)\n * ```\n */\nexport const uuidv7: UuidV7 = Object.assign(v7, {\n  toBytes: parseUuid,\n  fromBytes: formatUuid,\n  timestamp,\n  isValid,\n  NIL: '00000000-0000-0000-0000-000000000000',\n  MAX: 'ffffffff-ffff-ffff-ffff-ffffffffffff',\n})\n\nexport { BufferError, InvalidInputError, ParseError, UniqueIdError } from '../errors'\n"],"mappings":"iMA4BA,MAAM,EAAgB,yEAIhB,EAAc,IAAI,WAAW,GAAG,CAehCA,EAAiB,CAAE,MAAO,KAAW,IAAK,EAAG,CAEnD,SAAS,EACP,EACA,EACA,EACA,EACA,EAAS,EACG,CACZ,GAAI,EAAK,OAAS,GAChB,MAAM,IAAI,EAAkB,8BAA+B,oCAAoC,CAGjG,GAAI,EAAS,GAAK,EAAS,GAAK,EAAI,OAClC,MAAM,IAAI,EACR,4BACA,mBAAmB,EAAO,GAAG,EAAS,GAAG,0BAC1C,CA8BH,MA3BA,KAAU,KAAK,KAAK,CAGpB,IAAS,EAAK,IAAM,GAAO,EAAK,IAAM,GAAO,EAAK,IAAM,EAAK,EAAK,GAIlE,EAAI,KAAa,EAAQ,cAAiB,IAC1C,EAAI,KAAa,EAAQ,WAAe,IACxC,EAAI,KAAa,EAAQ,SAAa,IACtC,EAAI,KAAa,EAAQ,MAAW,IACpC,EAAI,KAAa,EAAQ,IAAS,IAClC,EAAI,KAAY,EAAQ,IAGxB,EAAI,KAAY,IAAS,IAAQ,GAAM,GACvC,EAAI,KAAa,IAAQ,GAAM,IAC/B,EAAI,KAAY,IAAS,IAAQ,GAAM,GACvC,EAAI,KAAa,IAAQ,EAAK,IAE9B,EAAI,KAAc,GAAO,EAAK,IAAS,EAAK,IAAM,EAClD,EAAI,KAAY,EAAK,IACrB,EAAI,KAAY,EAAK,IACrB,EAAI,KAAY,EAAK,IACrB,EAAI,KAAY,EAAK,IACrB,EAAI,KAAY,EAAK,IAEd,EAWT,SAAS,EAAyC,EAAyB,EAAY,EAAgC,CACrH,IAAIC,EAEJ,GAAI,EACF,EAAQ,EAAQ,EAAQ,QAAU,GAAK,CAAE,EAAQ,MAAO,EAAQ,IAAK,GAAO,EAAa,EAAM,EAAS,EAAE,KACrG,CAEL,IAAM,EAAM,KAAK,KAAK,CAChB,EAAO,GAAK,CAGd,EAAM,EAAM,OACd,EAAM,IAAO,EAAK,IAAM,GAAO,EAAK,IAAM,GAAO,EAAK,IAAM,EAAK,EAAK,GACtE,EAAM,MAAQ,IAEd,EAAM,IAAO,EAAM,IAAM,EAAK,EAC1B,EAAM,MAAQ,GAChB,EAAM,SAIV,EAAQ,EAAQ,EAAM,EAAM,MAAO,EAAM,IAAK,GAAO,EAAa,EAAM,EAAS,EAAE,CAGrF,OAAO,EAAO,EAAiB,EAAW,EAAM,CAGlD,SAAS,EAAU,EAAoB,CACrC,IAAM,EAAQ,EAAU,EAAG,CACvB,EAAQ,EACZ,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,GAAK,EAC1B,EAAQ,EAAQ,IAAM,EAAM,GAE9B,OAAO,EAGT,SAAS,EAAQ,EAA2B,CAC1C,OAAO,OAAO,GAAO,UAAY,EAAc,KAAK,EAAG,CA6BzD,MAAaC,EAAiB,OAAO,OAAO,EAAI,CAC9C,QAAS,EACT,UAAW,EACX,YACA,UACA,IAAK,uCACL,IAAK,uCACN,CAAC"}