{"version":3,"file":"v1.cjs","names":["rng","unsafeStringify"],"sources":["../../../src/utils/uuid/v1.ts"],"sourcesContent":["import rng from \"./rng.js\";\nimport { unsafeStringify } from \"./stringify.js\";\nimport type { UUIDTypes, Version1Options } from \"./types.js\";\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\ntype V1State = {\n  node?: Uint8Array; // node id (47-bit random)\n  clockseq?: number; // sequence number (14-bit)\n\n  // v1 & v6 timestamps are a pain to deal with.  They specify time from the\n  // Gregorian epoch in 100ns intervals, which requires values with 57+ bits of\n  // precision.  But that's outside the precision of IEEE754 floats (i.e. JS\n  // numbers).  To work around this, we represent them internally using 'msecs'\n  // (milliseconds since unix epoch) and 'nsecs' (100-nanoseconds offset from\n  // `msecs`).\n\n  msecs?: number; // timestamp (milliseconds, unix epoch)\n  nsecs?: number; // timestamp (100-nanoseconds offset from 'msecs')\n};\n\nconst _state: V1State = {};\n\nfunction v1(\n  options?: Version1Options,\n  buf?: undefined,\n  offset?: number\n): string;\nfunction v1<Buf extends Uint8Array = Uint8Array>(\n  options: Version1Options | undefined,\n  buf: Buf,\n  offset?: number\n): Buf;\nfunction v1<TBuf extends Uint8Array = Uint8Array>(\n  options?: Version1Options,\n  buf?: TBuf,\n  offset?: number\n): UUIDTypes<TBuf> {\n  let bytes: Uint8Array;\n\n  // Extract _v6 flag from options, clearing options if appropriate\n  const isV6 = options?._v6 ?? false;\n  if (options) {\n    const optionsKeys = Object.keys(options);\n    if (optionsKeys.length === 1 && optionsKeys[0] === \"_v6\") {\n      options = undefined;\n    }\n  }\n\n  if (options) {\n    // With options: Make UUID independent of internal state\n    bytes = v1Bytes(\n      options.random ?? options.rng?.() ?? rng(),\n      options.msecs,\n      options.nsecs,\n      options.clockseq,\n      options.node,\n      buf,\n      offset\n    );\n  } else {\n    // Without options: Make UUID from internal state\n    const now = Date.now();\n    const rnds = rng();\n\n    updateV1State(_state, now, rnds);\n\n    // Geenerate UUID.  Note that v6 uses random values for `clockseq` and\n    // `node`.\n    //\n    // https://www.rfc-editor.org/rfc/rfc9562.html#section-5.6-4\n    bytes = v1Bytes(\n      rnds,\n      _state.msecs,\n      _state.nsecs,\n      // v6 UUIDs get random `clockseq` and `node` for every UUID\n      // https://www.rfc-editor.org/rfc/rfc9562.html#section-5.6-4\n      isV6 ? undefined : _state.clockseq,\n      isV6 ? undefined : _state.node,\n      buf,\n      offset\n    );\n  }\n\n  return buf ?? unsafeStringify(bytes);\n}\n\n// (Private!)  Do not use.  This method is only exported for testing purposes\n// and may change without notice.\nexport function updateV1State(state: V1State, now: number, rnds: Uint8Array) {\n  state.msecs ??= -Infinity;\n  state.nsecs ??= 0;\n\n  // Update timestamp\n  if (now === state.msecs) {\n    // Same msec-interval = simulate higher clock resolution by bumping `nsecs`\n    // https://www.rfc-editor.org/rfc/rfc9562.html#section-6.1-2.6\n    state.nsecs++;\n\n    // Check for `nsecs` overflow (nsecs is capped at 10K intervals / msec)\n    if (state.nsecs >= 10000) {\n      // Prior to uuid@11 this would throw an error, however the RFCs allow for\n      // changing the node in this case.  This slightly breaks monotonicity at\n      // msec granularity, but that's not a significant concern.\n      // https://www.rfc-editor.org/rfc/rfc9562.html#section-6.1-2.16\n      state.node = undefined;\n      state.nsecs = 0;\n    }\n  } else if (now > state.msecs) {\n    // Reset nsec counter when clock advances to a new msec interval\n    state.nsecs = 0;\n  } else if (now < state.msecs) {\n    // Handle clock regression\n    // https://www.rfc-editor.org/rfc/rfc9562.html#section-6.1-2.7\n    //\n    // Note: Unsetting node here causes both it and clockseq to be randomized,\n    // below.\n    state.node = undefined;\n  }\n\n  // Init node and clock sequence (do this after timestamp update which may\n  // reset the node) https://www.rfc-editor.org/rfc/rfc9562.html#section-5.1-7\n  //\n  // Note:\n  if (!state.node) {\n    state.node = rnds.slice(10, 16);\n\n    // Set multicast bit\n    // https://www.rfc-editor.org/rfc/rfc9562.html#section-6.10-3\n    state.node[0] |= 0x01; // Set multicast bit\n\n    // Clock sequence must be randomized\n    // https://www.rfc-editor.org/rfc/rfc9562.html#section-5.1-8\n    state.clockseq = ((rnds[8] << 8) | rnds[9]) & 0x3fff;\n  }\n\n  state.msecs = now;\n\n  return state;\n}\n\nfunction v1Bytes(\n  rnds: Uint8Array,\n  msecs?: number,\n  nsecs?: number,\n  clockseq?: number,\n  node?: Uint8Array,\n  buf?: Uint8Array,\n  offset = 0\n) {\n  if (rnds.length < 16) {\n    throw new Error(\"Random bytes length must be >= 16\");\n  }\n\n  // Defaults\n  if (!buf) {\n    buf = new Uint8Array(16);\n    offset = 0;\n  } else {\n    if (offset < 0 || offset + 16 > buf.length) {\n      throw new RangeError(\n        `UUID byte range ${offset}:${offset + 15} is out of buffer bounds`\n      );\n    }\n  }\n\n  msecs ??= Date.now();\n  nsecs ??= 0;\n  clockseq ??= ((rnds[8] << 8) | rnds[9]) & 0x3fff;\n  node ??= rnds.slice(10, 16);\n\n  // Offset to Gregorian epoch\n  // https://www.rfc-editor.org/rfc/rfc9562.html#section-5.1-1\n  msecs += 12219292800000;\n\n  // `time_low`\n  const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n  buf[offset++] = (tl >>> 24) & 0xff;\n  buf[offset++] = (tl >>> 16) & 0xff;\n  buf[offset++] = (tl >>> 8) & 0xff;\n  buf[offset++] = tl & 0xff;\n\n  // `time_mid`\n  const tmh = ((msecs / 0x100000000) * 10000) & 0xfffffff;\n  buf[offset++] = (tmh >>> 8) & 0xff;\n  buf[offset++] = tmh & 0xff;\n\n  // `time_high_and_version`\n  buf[offset++] = ((tmh >>> 24) & 0xf) | 0x10; // include version\n  buf[offset++] = (tmh >>> 16) & 0xff;\n\n  // `clock_seq_hi_and_reserved` | variant\n  buf[offset++] = (clockseq >>> 8) | 0x80;\n\n  // `clock_seq_low`\n  buf[offset++] = clockseq & 0xff;\n\n  // `node`\n  for (let n = 0; n < 6; ++n) {\n    buf[offset++] = node[n];\n  }\n\n  return buf;\n}\n\nexport default v1;\n"],"mappings":";;;AAwBA,MAAM,SAAkB,EAAE;AAY1B,SAAS,GACP,SACA,KACA,QACiB;CACjB,IAAI;CAGJ,MAAM,OAAO,SAAS,OAAO;AAC7B,KAAI,SAAS;EACX,MAAM,cAAc,OAAO,KAAK,QAAQ;AACxC,MAAI,YAAY,WAAW,KAAK,YAAY,OAAO,MACjD,WAAU,KAAA;;AAId,KAAI,QAEF,SAAQ,QACN,QAAQ,UAAU,QAAQ,OAAO,IAAIA,YAAAA,SAAK,EAC1C,QAAQ,OACR,QAAQ,OACR,QAAQ,UACR,QAAQ,MACR,KACA,OACD;MACI;EAEL,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,OAAOA,YAAAA,SAAK;AAElB,gBAAc,QAAQ,KAAK,KAAK;AAMhC,UAAQ,QACN,MACA,OAAO,OACP,OAAO,OAGP,OAAO,KAAA,IAAY,OAAO,UAC1B,OAAO,KAAA,IAAY,OAAO,MAC1B,KACA,OACD;;AAGH,QAAO,OAAOC,kBAAAA,gBAAgB,MAAM;;AAKtC,SAAgB,cAAc,OAAgB,KAAa,MAAkB;AAC3E,OAAM,UAAU;AAChB,OAAM,UAAU;AAGhB,KAAI,QAAQ,MAAM,OAAO;AAGvB,QAAM;AAGN,MAAI,MAAM,SAAS,KAAO;AAKxB,SAAM,OAAO,KAAA;AACb,SAAM,QAAQ;;YAEP,MAAM,MAAM,MAErB,OAAM,QAAQ;UACL,MAAM,MAAM,MAMrB,OAAM,OAAO,KAAA;AAOf,KAAI,CAAC,MAAM,MAAM;AACf,QAAM,OAAO,KAAK,MAAM,IAAI,GAAG;AAI/B,QAAM,KAAK,MAAM;AAIjB,QAAM,YAAa,KAAK,MAAM,IAAK,KAAK,MAAM;;AAGhD,OAAM,QAAQ;AAEd,QAAO;;AAGT,SAAS,QACP,MACA,OACA,OACA,UACA,MACA,KACA,SAAS,GACT;AACA,KAAI,KAAK,SAAS,GAChB,OAAM,IAAI,MAAM,oCAAoC;AAItD,KAAI,CAAC,KAAK;AACR,QAAM,IAAI,WAAW,GAAG;AACxB,WAAS;YAEL,SAAS,KAAK,SAAS,KAAK,IAAI,OAClC,OAAM,IAAI,WACR,mBAAmB,OAAO,GAAG,SAAS,GAAG,0BAC1C;AAIL,WAAU,KAAK,KAAK;AACpB,WAAU;AACV,eAAe,KAAK,MAAM,IAAK,KAAK,MAAM;AAC1C,UAAS,KAAK,MAAM,IAAI,GAAG;AAI3B,UAAS;CAGT,MAAM,OAAO,QAAQ,aAAa,MAAQ,SAAS;AACnD,KAAI,YAAa,OAAO,KAAM;AAC9B,KAAI,YAAa,OAAO,KAAM;AAC9B,KAAI,YAAa,OAAO,IAAK;AAC7B,KAAI,YAAY,KAAK;CAGrB,MAAM,MAAQ,QAAQ,aAAe,MAAS;AAC9C,KAAI,YAAa,QAAQ,IAAK;AAC9B,KAAI,YAAY,MAAM;AAGtB,KAAI,YAAc,QAAQ,KAAM,KAAO;AACvC,KAAI,YAAa,QAAQ,KAAM;AAG/B,KAAI,YAAa,aAAa,IAAK;AAGnC,KAAI,YAAY,WAAW;AAG3B,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,EAAE,EACvB,KAAI,YAAY,KAAK;AAGvB,QAAO"}