UNPKG

ui7

Version:

Generate sortable, timestamped UUID's, based on the new-uuid-format-04 RFC draft

168 lines (167 loc) 5.03 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var mod_exports = {}; __export(mod_exports, { ParseError: () => ParseError, bufferedRandom: () => bufferedRandom, default: () => mod_default, generator: () => generator, monotonic: () => monotonic, pattern: () => pattern, random: () => random, timestamp: () => timestamp, v7: () => v7 }); module.exports = __toCommonJS(mod_exports); var crypto = globalThis.crypto || require("crypto").webcrypto || function(crypto2) { return { getRandomValues(array) { return crypto2.randomFillSync(array); } }; }(require("crypto")); const v7 = (opt) => { const time = getTime(opt); let dashes = true; let upper = false; let version = 7 << 4; let rand = random; if (typeof opt === "object" && opt !== null && !(opt instanceof Date)) { if (opt.dashes != null) dashes = opt.dashes; if (opt.version != null) version = (opt.version & 15) << 4; if (opt.upper != null) upper = opt.upper; if (opt.entropy != null) rand = opt.entropy === 0 || opt.entropy === 255 ? constantEntropy(opt.entropy) : opt.entropy; } let timestamp2 = hex(time, 12); if (dashes) timestamp2 = timestamp2.slice(0, 8) + "-" + timestamp2.slice(8); const suffixBytes = Array(10); rand(10, time).forEach((b, i) => { if (i === 0) { b = version | b & 15; } else if (i === 2) { b = variant | b & 63; } suffixBytes[i] = hex(b); }); const suffix = suffixBytes.join(""); const id = dashes ? `${timestamp2}-${suffix.slice(0, 4)}-${suffix.slice(4, 8)}-${suffix.slice(8)}` : timestamp2 + suffix; return upper ? id.toUpperCase() : id; function constantEntropy(k) { return (n) => new Uint8Array(n).map(() => k); } }; var mod_default = v7; const generator = (options) => { options = { entropy: monotonic(), ...options }; return (opt) => { if (opt == null) return v7(options); if (opt instanceof Date || typeof opt === "number" || typeof opt === "function") return v7({ ...options, time: opt }); return v7({ ...options, ...opt }); }; }; const timestamp = (uuid) => { const match = pattern.exec(uuid); if (match == null) throw new ParseError("Invalid v7 UUID; cannot determine timestamp"); const ts = match[1].replace("-", ""); return parseInt(ts, 16); }; const pattern = /^([0-9a-f]{8}-?[0-9a-f]{4})-?7([0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12})$/i; const bufferedRandom = (blockSize = 200) => { let bytes; let buffer; let pos; return (size) => { if (size > blockSize) { bytes = void 0; blockSize = size; } if (!bytes) { bytes = new Uint8Array(blockSize); buffer = bytes.buffer; crypto.getRandomValues(bytes); pos = 0; } let next = pos + size; if (next >= blockSize) { const leftover = blockSize - pos; bytes.copyWithin(0, pos); crypto.getRandomValues(new Uint8Array(buffer, leftover)); pos = 0; next = size; } const result = new Uint8Array(buffer, pos, size); pos = next; return result; }; }; const random = bufferedRandom(); const monotonic = (entropy = random) => { let bytes = new Uint8Array(10); let randomBytes = new Uint8Array(bytes.buffer, 2); let lastTimestamp = 0; let seq; return (size, timestamp2) => { if (bytes.byteLength !== size) { bytes = new Uint8Array(size); randomBytes = new Uint8Array(bytes.buffer, 2); } if (timestamp2 > lastTimestamp) { bytes.set(entropy(10, timestamp2)); bytes[0] &= 7; lastTimestamp = timestamp2; seq = void 0; } else { if (seq === void 0) seq = (bytes[0] & 15) << 8 | bytes[1]; seq++; randomBytes.set(entropy(8, timestamp2)); bytes[0] = seq >> 8 & 255; bytes[1] = seq & 255; } return bytes; }; }; class ParseError extends Error { name = "ParseError"; } const getTime = (time) => { if (time == null) return Date.now(); if (typeof time === "number") return time; if (time instanceof Date) return +time; if (typeof time === "function") return time(); return getTime(time.time); }; const hex = (n, width = 2) => n.toString(16).padStart(width, "0"); const variant = 2 << 6; //# sourceMappingURL=mod.cjs.map