{"version":3,"sources":["../src/ulid/index.ts"],"names":["monotonicFactory","decodeTime"],"mappings":"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","file":"index.cjs","sourcesContent":["import { monotonicFactory, decodeTime } from \"ulidx\"\r\n\r\n// Constants\r\nconst CROCKFORD32 = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\"\r\nconst ULID_LENGTH = 26 // Standard ULID length\r\n\r\n// Precompute decode map for performance\r\nconst DECODE_MAP = new Uint8Array(128).fill(255)\r\nfor (let i = 0; i < CROCKFORD32.length; i++) {\r\n  DECODE_MAP[CROCKFORD32.charCodeAt(i)] = i\r\n}\r\n\r\n// Create monotonic ULID generator\r\nconst ulidGenerator = monotonicFactory()\r\n\r\n/**\r\n * Generate a ULID (Universally Unique Lexicographically Sortable ID).\r\n * Returns 26 characters with last character always '0' for perfect binary conversion.\r\n *\r\n * This ensures 100% lossless binary conversion (128 bits) while maintaining\r\n * full ULID spec compliance and interoperability with other ULID systems.\r\n *\r\n * Uses monotonic mode by default - ensures IDs are always increasing,\r\n * even if the system clock goes backwards.\r\n *\r\n * @param seedTime Optional timestamp in milliseconds to use for ID generation\r\n * @returns 26-character ULID string (last char always '0')\r\n */\r\nexport function generateUlid(seedTime?: number): string {\r\n  const id = seedTime !== undefined ? ulidGenerator(seedTime) : ulidGenerator()\r\n  // Replace last char with '0' for lossless binary conversion (128 bits)\r\n  return id.substring(0, 25) + \"0\"\r\n}\r\n\r\n/**\r\n * Validate if a string is a valid ULID format.\r\n *\r\n * @param id The string to validate\r\n * @returns true if valid ULID format (26 characters, valid Crockford Base32)\r\n */\r\nexport function isValidUlid(id: string): boolean {\r\n  if (!id || typeof id !== \"string\" || id.length !== ULID_LENGTH) return false\r\n\r\n  // Validate all characters are valid Crockford Base32\r\n  for (let i = 0; i < id.length; i++) {\r\n    const charCode = id.charCodeAt(i)\r\n    const upperCharCode = id.toUpperCase().charCodeAt(i)\r\n    if (DECODE_MAP[charCode] === 255 && DECODE_MAP[upperCharCode] === 255) {\r\n      return false\r\n    }\r\n  }\r\n\r\n  return true\r\n}\r\n\r\n/**\r\n * Decode timestamp from a ULID string.\r\n *\r\n * @param id The ULID string (26 characters)\r\n * @returns Timestamp in milliseconds since Unix epoch\r\n * @throws Error if invalid ULID\r\n */\r\nexport function decodeTimeFromUlid(id: string): number {\r\n  if (!isValidUlid(id)) {\r\n    throw new Error(\"Invalid ULID format\")\r\n  }\r\n  return decodeTime(id)\r\n}\r\n\r\n/**\r\n * Get the age of a ULID in milliseconds.\r\n *\r\n * @param id The ULID string\r\n * @returns Age in milliseconds\r\n * @throws Error if invalid ULID\r\n */\r\nexport function getUlidAge(id: string): number {\r\n  return Date.now() - decodeTimeFromUlid(id)\r\n}\r\n\r\n/**\r\n * Parse a ULID and extract all its components.\r\n *\r\n * @param id The ULID string\r\n * @returns Object containing timestamp (ms), timestampSeconds, and age (ms)\r\n * @throws Error if invalid ULID\r\n */\r\nexport function parseUlid(id: string): {\r\n  timestamp: number\r\n  timestampSeconds: number\r\n  age: number\r\n} {\r\n  const timestamp = decodeTimeFromUlid(id)\r\n  const age = Date.now() - timestamp\r\n\r\n  return {\r\n    timestamp,\r\n    timestampSeconds: Math.floor(timestamp / 1000),\r\n    age,\r\n  }\r\n}\r\n\r\n/**\r\n * Convert ULID (26-char base32) → 16-byte binary for lossless storage.\r\n * Works perfectly because last character is always '0' (uses only 128 bits).\r\n *\r\n * @param id The ULID string (26 characters)\r\n * @returns 16-byte Uint8Array\r\n * @throws Error if invalid ULID\r\n */\r\nexport function ulidToBinary(id: string): Uint8Array {\r\n  if (!isValidUlid(id)) {\r\n    throw new Error(`Invalid ULID: must be ${ULID_LENGTH} characters`)\r\n  }\r\n\r\n  const bytes = new Uint8Array(16)\r\n  let bitBuffer = 0\r\n  let bitsInBuffer = 0\r\n  let bytePos = 0\r\n\r\n  // Process all 26 characters (130 bits, but last 2 bits are always 0)\r\n  for (let i = 0; i < ULID_LENGTH; i++) {\r\n    const charCode = id.charCodeAt(i)\r\n    const value =\r\n      DECODE_MAP[charCode] !== 255\r\n        ? DECODE_MAP[charCode]\r\n        : DECODE_MAP[id.toUpperCase().charCodeAt(i)]\r\n\r\n    bitBuffer = (bitBuffer << 5) | value\r\n    bitsInBuffer += 5\r\n\r\n    // Flush complete bytes\r\n    while (bitsInBuffer >= 8) {\r\n      bitsInBuffer -= 8\r\n      if (bytePos < 16) {\r\n        bytes[bytePos++] = (bitBuffer >> bitsInBuffer) & 0xff\r\n      }\r\n    }\r\n  }\r\n\r\n  // No remaining bits to handle since last char '0' contributes only to complete bytes\r\n  return bytes\r\n}\r\n\r\n/**\r\n * Convert 16-byte binary ULID → 26-char string (lossless).\r\n * Last character will always be '0' (maintains consistency with generateUlid).\r\n *\r\n * @param input Binary ULID (16 bytes)\r\n * @returns 26-character ULID string\r\n * @throws Error if invalid input\r\n */\r\nexport function binaryToUlid(input: Uint8Array | Buffer): string {\r\n  const bytes = input instanceof Buffer ? new Uint8Array(input) : input\r\n\r\n  if (!(bytes instanceof Uint8Array) || bytes.length !== 16) {\r\n    throw new Error(\"Invalid binary ULID: must be 16 bytes\")\r\n  }\r\n\r\n  let bitBuffer = 0\r\n  let bitsInBuffer = 0\r\n  let id = \"\"\r\n\r\n  // Process all 16 bytes\r\n  for (let i = 0; i < 16; i++) {\r\n    bitBuffer = (bitBuffer << 8) | bytes[i]\r\n    bitsInBuffer += 8\r\n\r\n    // Extract 5-bit groups\r\n    while (bitsInBuffer >= 5) {\r\n      bitsInBuffer -= 5\r\n      id += CROCKFORD32[(bitBuffer >> bitsInBuffer) & 31]\r\n    }\r\n  }\r\n\r\n  // Add final character (will be '0' due to padding)\r\n  if (bitsInBuffer > 0) {\r\n    id += CROCKFORD32[(bitBuffer << (5 - bitsInBuffer)) & 31]\r\n  }\r\n\r\n  // Ensure exactly 26 characters with last char '0'\r\n  return id.substring(0, 25) + \"0\"\r\n}\r\n"]}