UNPKG

hot-updater

Version:

React Native OTA solution for self-hosted

360 lines (357 loc) 13.6 kB
const require_picocolors$1 = require('../picocolors-nLcU57DT.cjs'); const fs = require_picocolors$1.__toESM(require("fs")); const path = require_picocolors$1.__toESM(require("path")); //#region ../../node_modules/.pnpm/uuidv7@1.0.2/node_modules/uuidv7/dist/index.js /** * uuidv7: A JavaScript implementation of UUID version 7 * * Copyright 2021-2024 LiosK * * @license Apache-2.0 * @packageDocumentation */ const DIGITS = "0123456789abcdef"; /** Represents a UUID as a 16-byte byte array. */ var UUID = class UUID { /** @param bytes - The 16-byte byte array representation. */ constructor(bytes) { this.bytes = bytes; } /** * Creates an object from the internal representation, a 16-byte byte array * containing the binary UUID representation in the big-endian byte order. * * This method does NOT shallow-copy the argument, and thus the created object * holds the reference to the underlying buffer. * * @throws TypeError if the length of the argument is not 16. */ static ofInner(bytes) { if (bytes.length !== 16) throw new TypeError("not 128-bit length"); else return new UUID(bytes); } /** * Builds a byte array from UUIDv7 field values. * * @param unixTsMs - A 48-bit `unix_ts_ms` field value. * @param randA - A 12-bit `rand_a` field value. * @param randBHi - The higher 30 bits of 62-bit `rand_b` field value. * @param randBLo - The lower 32 bits of 62-bit `rand_b` field value. * @throws RangeError if any field value is out of the specified range. */ static fromFieldsV7(unixTsMs, randA, randBHi, randBLo) { if (!Number.isInteger(unixTsMs) || !Number.isInteger(randA) || !Number.isInteger(randBHi) || !Number.isInteger(randBLo) || unixTsMs < 0 || randA < 0 || randBHi < 0 || randBLo < 0 || unixTsMs > 0xffffffffffff || randA > 4095 || randBHi > 1073741823 || randBLo > 4294967295) throw new RangeError("invalid field value"); const bytes = new Uint8Array(16); bytes[0] = unixTsMs / 2 ** 40; bytes[1] = unixTsMs / 2 ** 32; bytes[2] = unixTsMs / 2 ** 24; bytes[3] = unixTsMs / 2 ** 16; bytes[4] = unixTsMs / 2 ** 8; bytes[5] = unixTsMs; bytes[6] = 112 | randA >>> 8; bytes[7] = randA; bytes[8] = 128 | randBHi >>> 24; bytes[9] = randBHi >>> 16; bytes[10] = randBHi >>> 8; bytes[11] = randBHi; bytes[12] = randBLo >>> 24; bytes[13] = randBLo >>> 16; bytes[14] = randBLo >>> 8; bytes[15] = randBLo; return new UUID(bytes); } /** * Builds a byte array from a string representation. * * This method accepts the following formats: * * - 32-digit hexadecimal format without hyphens: `0189dcd553117d408db09496a2eef37b` * - 8-4-4-4-12 hyphenated format: `0189dcd5-5311-7d40-8db0-9496a2eef37b` * - Hyphenated format with surrounding braces: `{0189dcd5-5311-7d40-8db0-9496a2eef37b}` * - RFC 9562 URN format: `urn:uuid:0189dcd5-5311-7d40-8db0-9496a2eef37b` * * Leading and trailing whitespaces represents an error. * * @throws SyntaxError if the argument could not parse as a valid UUID string. */ static parse(uuid) { var _a, _b, _c, _d; let hex = void 0; switch (uuid.length) { case 32: hex = (_a = /^[0-9a-f]{32}$/i.exec(uuid)) === null || _a === void 0 ? void 0 : _a[0]; break; case 36: hex = (_b = /^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/i.exec(uuid)) === null || _b === void 0 ? void 0 : _b.slice(1, 6).join(""); break; case 38: hex = (_c = /^\{([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})\}$/i.exec(uuid)) === null || _c === void 0 ? void 0 : _c.slice(1, 6).join(""); break; case 45: hex = (_d = /^urn:uuid:([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/i.exec(uuid)) === null || _d === void 0 ? void 0 : _d.slice(1, 6).join(""); break; default: break; } if (hex) { const inner = new Uint8Array(16); for (let i = 0; i < 16; i += 4) { const n = parseInt(hex.substring(2 * i, 2 * i + 8), 16); inner[i + 0] = n >>> 24; inner[i + 1] = n >>> 16; inner[i + 2] = n >>> 8; inner[i + 3] = n; } return new UUID(inner); } else throw new SyntaxError("could not parse UUID string"); } /** * @returns The 8-4-4-4-12 canonical hexadecimal string representation * (`0189dcd5-5311-7d40-8db0-9496a2eef37b`). */ toString() { let text = ""; for (let i = 0; i < this.bytes.length; i++) { text += DIGITS.charAt(this.bytes[i] >>> 4); text += DIGITS.charAt(this.bytes[i] & 15); if (i === 3 || i === 5 || i === 7 || i === 9) text += "-"; } return text; } /** * @returns The 32-digit hexadecimal representation without hyphens * (`0189dcd553117d408db09496a2eef37b`). */ toHex() { let text = ""; for (let i = 0; i < this.bytes.length; i++) { text += DIGITS.charAt(this.bytes[i] >>> 4); text += DIGITS.charAt(this.bytes[i] & 15); } return text; } /** @returns The 8-4-4-4-12 canonical hexadecimal string representation. */ toJSON() { return this.toString(); } /** * Reports the variant field value of the UUID or, if appropriate, "NIL" or * "MAX". * * For convenience, this method reports "NIL" or "MAX" if `this` represents * the Nil or Max UUID, although the Nil and Max UUIDs are technically * subsumed under the variants `0b0` and `0b111`, respectively. */ getVariant() { const n = this.bytes[8] >>> 4; if (n < 0) throw new Error("unreachable"); else if (n <= 7) return this.bytes.every((e) => e === 0) ? "NIL" : "VAR_0"; else if (n <= 11) return "VAR_10"; else if (n <= 13) return "VAR_110"; else if (n <= 15) return this.bytes.every((e) => e === 255) ? "MAX" : "VAR_RESERVED"; else throw new Error("unreachable"); } /** * Returns the version field value of the UUID or `undefined` if the UUID does * not have the variant field value of `0b10`. */ getVersion() { return this.getVariant() === "VAR_10" ? this.bytes[6] >>> 4 : void 0; } /** Creates an object from `this`. */ clone() { return new UUID(this.bytes.slice(0)); } /** Returns true if `this` is equivalent to `other`. */ equals(other) { return this.compareTo(other) === 0; } /** * Returns a negative integer, zero, or positive integer if `this` is less * than, equal to, or greater than `other`, respectively. */ compareTo(other) { for (let i = 0; i < 16; i++) { const diff = this.bytes[i] - other.bytes[i]; if (diff !== 0) return Math.sign(diff); } return 0; } }; /** * Encapsulates the monotonic counter state. * * This class provides APIs to utilize a separate counter state from that of the * global generator used by {@link uuidv7} and {@link uuidv7obj}. In addition to * the default {@link generate} method, this class has {@link generateOrAbort} * that is useful to absolutely guarantee the monotonically increasing order of * generated UUIDs. See their respective documentation for details. */ var V7Generator = class { /** * Creates a generator object with the default random number generator, or * with the specified one if passed as an argument. The specified random * number generator should be cryptographically strong and securely seeded. */ constructor(randomNumberGenerator) { this.timestamp = 0; this.counter = 0; this.random = randomNumberGenerator !== null && randomNumberGenerator !== void 0 ? randomNumberGenerator : getDefaultRandom(); } /** * Generates a new UUIDv7 object from the current timestamp, or resets the * generator upon significant timestamp rollback. * * This method returns a monotonically increasing UUID by reusing the previous * timestamp even if the up-to-date timestamp is smaller than the immediately * preceding UUID's. However, when such a clock rollback is considered * significant (i.e., by more than ten seconds), this method resets the * generator and returns a new UUID based on the given timestamp, breaking the * increasing order of UUIDs. * * See {@link generateOrAbort} for the other mode of generation and * {@link generateOrResetCore} for the low-level primitive. */ generate() { return this.generateOrResetCore(Date.now(), 1e4); } /** * Generates a new UUIDv7 object from the current timestamp, or returns * `undefined` upon significant timestamp rollback. * * This method returns a monotonically increasing UUID by reusing the previous * timestamp even if the up-to-date timestamp is smaller than the immediately * preceding UUID's. However, when such a clock rollback is considered * significant (i.e., by more than ten seconds), this method aborts and * returns `undefined` immediately. * * See {@link generate} for the other mode of generation and * {@link generateOrAbortCore} for the low-level primitive. */ generateOrAbort() { return this.generateOrAbortCore(Date.now(), 1e4); } /** * Generates a new UUIDv7 object from the `unixTsMs` passed, or resets the * generator upon significant timestamp rollback. * * This method is equivalent to {@link generate} except that it takes a custom * timestamp and clock rollback allowance. * * @param rollbackAllowance - The amount of `unixTsMs` rollback that is * considered significant. A suggested value is `10_000` (milliseconds). * @throws RangeError if `unixTsMs` is not a 48-bit positive integer. */ generateOrResetCore(unixTsMs, rollbackAllowance) { let value = this.generateOrAbortCore(unixTsMs, rollbackAllowance); if (value === void 0) { this.timestamp = 0; value = this.generateOrAbortCore(unixTsMs, rollbackAllowance); } return value; } /** * Generates a new UUIDv7 object from the `unixTsMs` passed, or returns * `undefined` upon significant timestamp rollback. * * This method is equivalent to {@link generateOrAbort} except that it takes a * custom timestamp and clock rollback allowance. * * @param rollbackAllowance - The amount of `unixTsMs` rollback that is * considered significant. A suggested value is `10_000` (milliseconds). * @throws RangeError if `unixTsMs` is not a 48-bit positive integer. */ generateOrAbortCore(unixTsMs, rollbackAllowance) { const MAX_COUNTER = 4398046511103; if (!Number.isInteger(unixTsMs) || unixTsMs < 1 || unixTsMs > 0xffffffffffff) throw new RangeError("`unixTsMs` must be a 48-bit positive integer"); else if (rollbackAllowance < 0 || rollbackAllowance > 0xffffffffffff) throw new RangeError("`rollbackAllowance` out of reasonable range"); if (unixTsMs > this.timestamp) { this.timestamp = unixTsMs; this.resetCounter(); } else if (unixTsMs + rollbackAllowance >= this.timestamp) { this.counter++; if (this.counter > MAX_COUNTER) { this.timestamp++; this.resetCounter(); } } else return void 0; return UUID.fromFieldsV7(this.timestamp, Math.trunc(this.counter / 2 ** 30), this.counter & 2 ** 30 - 1, this.random.nextUint32()); } /** Initializes the counter at a 42-bit random integer. */ resetCounter() { this.counter = this.random.nextUint32() * 1024 + (this.random.nextUint32() & 1023); } /** * Generates a new UUIDv4 object utilizing the random number generator inside. * * @internal */ generateV4() { const bytes = new Uint8Array(Uint32Array.of(this.random.nextUint32(), this.random.nextUint32(), this.random.nextUint32(), this.random.nextUint32()).buffer); bytes[6] = 64 | bytes[6] >>> 4; bytes[8] = 128 | bytes[8] >>> 2; return UUID.ofInner(bytes); } }; /** Returns the default random number generator available in the environment. */ const getDefaultRandom = () => { if (typeof crypto !== "undefined" && typeof crypto.getRandomValues !== "undefined") return new BufferedCryptoRandom(); else { if (typeof UUIDV7_DENY_WEAK_RNG !== "undefined" && UUIDV7_DENY_WEAK_RNG) throw new Error("no cryptographically strong RNG available"); return { nextUint32: () => Math.trunc(Math.random() * 65536) * 65536 + Math.trunc(Math.random() * 65536) }; } }; /** * Wraps `crypto.getRandomValues()` to enable buffering; this uses a small * buffer by default to avoid both unbearable throughput decline in some * environments and the waste of time and space for unused values. */ var BufferedCryptoRandom = class { constructor() { this.buffer = new Uint32Array(8); this.cursor = 65535; } nextUint32() { if (this.cursor >= this.buffer.length) { crypto.getRandomValues(this.buffer); this.cursor = 0; } return this.buffer[this.cursor++]; } }; let defaultGenerator; /** * Generates a UUIDv7 string. * * @returns The 8-4-4-4-12 canonical hexadecimal string representation * ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"). */ const uuidv7 = () => uuidv7obj().toString(); /** Generates a UUIDv7 object. */ const uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator())).generate(); //#endregion //#region src/plugins/babel.ts var import_picocolors = require_picocolors$1.__toESM(require_picocolors$1.require_picocolors()); const NIL_UUID = "00000000-0000-0000-0000-000000000000"; const getBundleId = () => { const buildOutDir = process.env["BUILD_OUT_DIR"]; if (!buildOutDir) return NIL_UUID; const bundleIdPath = path.default.join(buildOutDir, "BUNDLE_ID"); let bundleId = uuidv7(); if (fs.default.existsSync(bundleIdPath)) bundleId = fs.default.readFileSync(bundleIdPath, "utf-8"); else { fs.default.writeFileSync(bundleIdPath, bundleId); console.log(import_picocolors.default.green(`[HotUpdater] Generated bundle ID: ${bundleId}`)); } return bundleId; }; function babel_default({ types: t }) { const bundleId = getBundleId(); return { name: "hot-updater-babel-plugin", visitor: { Identifier(path$2) { if (path$2.node.name === "__HOT_UPDATER_BUNDLE_ID") path$2.replaceWith(t.stringLiteral(bundleId)); } } }; } //#endregion module.exports = babel_default;