{"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,CAAC;AAYzB,SAAS,GACP,SACA,KACA,QACiB;CACjB,IAAI;CAGJ,MAAM,OAAO,SAAS,OAAO;CAC7B,IAAI,SAAS;EACX,MAAM,cAAc,OAAO,KAAK,OAAO;EACvC,IAAI,YAAY,WAAW,KAAK,YAAY,OAAO,OACjD,UAAU,KAAA;CAEd;CAEA,IAAI,SAEF,QAAQ,QACN,QAAQ,UAAU,QAAQ,MAAM,KAAKA,YAAAA,QAAI,GACzC,QAAQ,OACR,QAAQ,OACR,QAAQ,UACR,QAAQ,MACR,KACA,MACF;MACK;EAEL,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,OAAOA,YAAAA,QAAI;EAEjB,cAAc,QAAQ,KAAK,IAAI;EAM/B,QAAQ,QACN,MACA,OAAO,OACP,OAAO,OAGP,OAAO,KAAA,IAAY,OAAO,UAC1B,OAAO,KAAA,IAAY,OAAO,MAC1B,KACA,MACF;CACF;CAEA,OAAO,OAAOC,kBAAAA,gBAAgB,KAAK;AACrC;AAIA,SAAgB,cAAc,OAAgB,KAAa,MAAkB;CAC3E,MAAM,UAAU;CAChB,MAAM,UAAU;CAGhB,IAAI,QAAQ,MAAM,OAAO;EAGvB,MAAM;EAGN,IAAI,MAAM,SAAS,KAAO;GAKxB,MAAM,OAAO,KAAA;GACb,MAAM,QAAQ;EAChB;CACF,OAAO,IAAI,MAAM,MAAM,OAErB,MAAM,QAAQ;MACT,IAAI,MAAM,MAAM,OAMrB,MAAM,OAAO,KAAA;CAOf,IAAI,CAAC,MAAM,MAAM;EACf,MAAM,OAAO,KAAK,MAAM,IAAI,EAAE;EAI9B,MAAM,KAAK,MAAM;EAIjB,MAAM,YAAa,KAAK,MAAM,IAAK,KAAK,MAAM;CAChD;CAEA,MAAM,QAAQ;CAEd,OAAO;AACT;AAEA,SAAS,QACP,MACA,OACA,OACA,UACA,MACA,KACA,SAAS,GACT;CACA,IAAI,KAAK,SAAS,IAChB,MAAM,IAAI,MAAM,mCAAmC;CAIrD,IAAI,CAAC,KAAK;EACR,sBAAM,IAAI,WAAW,EAAE;EACvB,SAAS;CACX,OACE,IAAI,SAAS,KAAK,SAAS,KAAK,IAAI,QAClC,MAAM,IAAI,WACR,mBAAmB,OAAO,GAAG,SAAS,GAAG,yBAC3C;CAIJ,UAAU,KAAK,IAAI;CACnB,UAAU;CACV,cAAe,KAAK,MAAM,IAAK,KAAK,MAAM;CAC1C,SAAS,KAAK,MAAM,IAAI,EAAE;CAI1B,SAAS;CAGT,MAAM,OAAO,QAAQ,aAAa,MAAQ,SAAS;CACnD,IAAI,YAAa,OAAO,KAAM;CAC9B,IAAI,YAAa,OAAO,KAAM;CAC9B,IAAI,YAAa,OAAO,IAAK;CAC7B,IAAI,YAAY,KAAK;CAGrB,MAAM,MAAQ,QAAQ,aAAe,MAAS;CAC9C,IAAI,YAAa,QAAQ,IAAK;CAC9B,IAAI,YAAY,MAAM;CAGtB,IAAI,YAAc,QAAQ,KAAM,KAAO;CACvC,IAAI,YAAa,QAAQ,KAAM;CAG/B,IAAI,YAAa,aAAa,IAAK;CAGnC,IAAI,YAAY,WAAW;CAG3B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,EAAE,GACvB,IAAI,YAAY,KAAK;CAGvB,OAAO;AACT"}