import rng from './rng.js'; import { unsafeStringify } from './stringify.js'; const _state = {}; function v1(options, buf, offset) { let bytes; const isV6 = options?._v6 ?? false; if (options) { const optionsKeys = Object.keys(options); if (optionsKeys.length === 1 && optionsKeys[0] === '_v6') { options = undefined; } } if (options) { bytes = v1Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.nsecs, options.clockseq, options.node, buf, offset); } else { const now = Date.now(); const rnds = rng(); updateV1State(_state, now, rnds); bytes = v1Bytes(rnds, _state.msecs, _state.nsecs, isV6 ? undefined : _state.clockseq, isV6 ? undefined : _state.node, buf, offset); } return buf ? bytes : unsafeStringify(bytes); } export function updateV1State(state, now, rnds) { state.msecs ??= -Infinity; state.nsecs ??= 0; if (now === state.msecs) { state.nsecs++; if (state.nsecs >= 10000) { state.node = undefined; state.nsecs = 0; } } else if (now > state.msecs) { state.nsecs = 0; } else if (now < state.msecs) { state.node = undefined; } if (!state.node) { state.node = rnds.slice(10, 16); state.node[0] |= 0x01; state.clockseq = ((rnds[8] << 8) | rnds[9]) & 0x3fff; } state.msecs = now; return state; } function v1Bytes(rnds, msecs, nsecs, clockseq, node, buf, offset = 0) { if (!buf) { buf = new Uint8Array(16); offset = 0; } msecs ??= Date.now(); nsecs ??= 0; clockseq ??= ((rnds[8] << 8) | rnds[9]) & 0x3fff; node ??= rnds.slice(10, 16); msecs += 12219292800000; const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; buf[offset++] = (tl >>> 24) & 0xff; buf[offset++] = (tl >>> 16) & 0xff; buf[offset++] = (tl >>> 8) & 0xff; buf[offset++] = tl & 0xff; const tmh = ((msecs / 0x100000000) * 10000) & 0xfffffff; buf[offset++] = (tmh >>> 8) & 0xff; buf[offset++] = tmh & 0xff; buf[offset++] = ((tmh >>> 24) & 0xf) | 0x10; buf[offset++] = (tmh >>> 16) & 0xff; buf[offset++] = (clockseq >>> 8) | 0x80; buf[offset++] = clockseq & 0xff; for (let n = 0; n < 6; ++n) { buf[offset++] = node[n]; } return buf; } export default v1;