From 7dd42e474ba04db2cbf0df79cc02fb621a01721b Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Wed, 30 Sep 2026 10:30:57 -0400 Subject: [PATCH 01/18] Build lib/mappings.wasm with wasm-pack and wasm-bindgen The previous build pipeline could not be run at all on a current Rust toolchain. Three of its four tools failed outright: - cargo build: `undefined symbol: mapping_callback`, because the import blocks lacked `#[link(wasm_import_module = "env")]` and modern rust-lld rejects undefined symbols - wasm-gc 0.1.6: `InvalidTableReference(128)` - wasm-nm (which drives wasm-snip): `Not an unsigned 1-bit integer: 128` Only wasm-opt still worked, so the committed binary was not reproducible from its own sources. CI never noticed because the `wasm` job only ran a bare `cargo build` and never exercised build.py. Replace build.py and who-calls.py with build.sh, which drives wasm-pack. wasm-pack vendors its own wasm-bindgen and wasm-opt, reducing the four hand-installed binaries to one. Two targets are built, selected by the existing package.json#browser field: `nodejs` for CommonJS and `web` for browsers. Both emit the same .wasm; build.sh asserts this. The shipped filename stays lib/mappings.wasm so URLs passed to SourceMapConsumer.initialize keep working. Port the ABI to wasm-bindgen. allocate_mappings, parse_mappings, free_mappings and get_last_error collapse into parseMappings() plus a generated free(), so JS no longer hand-manages a buffer or memcpys into exports.memory.buffer. Callbacks are passed per-call, which removes the callbackStack and withMappingCallback machinery. Mapping construction stays in JS to keep every mapping on one hidden class. Note that a JS exception thrown from a mapping callback unwinds through the wasm frame and skips Rust's borrow guard, leaving the handle permanently borrowed so that free() then fails. The callback boundary is therefore declared `catch` and every query method returns Result<(), JsValue>, releasing the borrow before the exception propagates. Any future &mut self method that calls into JS needs the same treatment. Also drop the unused `rand` dependency, turn off `debug` in [profile.release] (it was responsible for 1.6 MB of debuginfo in a shipped artifact), and set opt-level="z", lto, codegen-units=1 and panic="abort". lib/mappings.wasm goes from 48,526 to 28,556 bytes. Commit both Cargo.lock files, pin the toolchain in rust-toolchain.toml, and add a `wasm-dist` CI job that rebuilds the committed artifacts and fails if they differ byte-for-byte. Verified that the job exits non-zero when the Rust sources drift. Bump eslint's ecmaVersion to 2020 for the dynamic import() in read-wasm-browser.js, and keep the generated glue out of eslint --fix and prettier so neither rewrites it and breaks the byte comparison. Co-Authored-By: Claude Opus 5 (1M context) --- .eslintrc.js | 2 +- .github/workflows/cargo.yml | 15 + .prettierignore | 10 + CONTRIBUTING.md | 46 +- lib/mappings-glue-browser.d.mts | 97 ++++ lib/mappings-glue-browser.mjs | 349 ++++++++++++ lib/mappings-glue.d.ts | 54 ++ lib/mappings-glue.js | 253 ++++++++ lib/mappings.wasm | Bin 48526 -> 28556 bytes lib/read-wasm-browser.js | 37 +- lib/read-wasm.js | 17 +- lib/source-map-consumer.js | 139 ++--- lib/wasm.js | 165 ++---- package.json | 2 +- test/test-source-map-consumer.js | 12 +- wasm-mappings/.gitignore | 3 +- wasm-mappings/CONTRIBUTING.md | 40 +- wasm-mappings/Cargo.lock | 198 +++++++ wasm-mappings/Cargo.toml | 3 +- wasm-mappings/build.sh | 61 ++ wasm-mappings/ci/script.sh | 18 +- wasm-mappings/rust-toolchain.toml | 10 + .../source-map-mappings-wasm-api/Cargo.lock | 128 +++++ .../source-map-mappings-wasm-api/Cargo.toml | 7 +- .../source-map-mappings-wasm-api/build.py | 162 ------ .../source-map-mappings-wasm-api/src/lib.rs | 539 ++++++------------ .../source-map-mappings-wasm-api/who-calls.py | 168 ------ wasm-mappings/src/lib.rs | 1 - 28 files changed, 1576 insertions(+), 960 deletions(-) create mode 100644 lib/mappings-glue-browser.d.mts create mode 100644 lib/mappings-glue-browser.mjs create mode 100644 lib/mappings-glue.d.ts create mode 100644 lib/mappings-glue.js create mode 100644 wasm-mappings/Cargo.lock create mode 100755 wasm-mappings/build.sh create mode 100644 wasm-mappings/rust-toolchain.toml create mode 100644 wasm-mappings/source-map-mappings-wasm-api/Cargo.lock delete mode 100755 wasm-mappings/source-map-mappings-wasm-api/build.py delete mode 100755 wasm-mappings/source-map-mappings-wasm-api/who-calls.py diff --git a/.eslintrc.js b/.eslintrc.js index e08d79be..ea9f7658 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -9,7 +9,7 @@ module.exports = { extends: ["prettier"], parserOptions: { - ecmaVersion: 9, + ecmaVersion: 2020, }, globals: { diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index bb422d05..7e5b5f9a 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -39,3 +39,18 @@ jobs: override: true default: true - run: JOB=${{ matrix.job }} ./ci/script.sh + + dist: + name: WASM binary is reproducible + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + # No toolchain override here on purpose: the build must use the version + # pinned in wasm-mappings/rust-toolchain.toml for the byte comparison + # to be meaningful. + # wasm-pack vendors its own wasm-bindgen and wasm-opt, so this is the + # only tool the build needs. + - uses: jetli/wasm-pack-action@v0.4.0 + with: + version: "v0.15.0" + - run: JOB=wasm-dist ./ci/script.sh diff --git a/.prettierignore b/.prettierignore index 9179b1bd..20576196 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,14 @@ bench/ +test/source-map-tests/ coverage/ node_modules/ target/ + +# Generated by wasm-mappings/build.sh; reformatting would break the +# byte-for-byte check in the `wasm-dist` CI job. +lib/mappings-glue.js +lib/mappings-glue.d.ts +lib/mappings-glue-browser.mjs +lib/mappings-glue-browser.d.mts +wasm-mappings/source-map-mappings-wasm-api/pkg-node/ +wasm-mappings/source-map-mappings-wasm-api/pkg-web/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c3509743..80f7872d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -134,40 +134,52 @@ Ensure that you have the Rust toolchain installed: $ curl https://sh.rustup.rs -sSf | sh ``` -The `wasm32-unknown-unknown` target is nightly-only at the time of writing. Use -`rustup` to ensure you have it installed: +The exact toolchain version is pinned in `wasm-mappings/rust-toolchain.toml` +and `rustup` will install it on demand, including the +`wasm32-unknown-unknown` target. +Note: The pin exists because CI rebuilds the +committed artifacts and fails if they differ byte-for-byte, which only works +if everyone builds with the same compiler. + +Install [`wasm-pack`](https://rustwasm.github.io/wasm-pack/), which is the +only other tool required -- it vendors its own `wasm-bindgen` and `wasm-opt`: ``` -$ rustup toolchain install nightly -$ rustup target add wasm32-unknown-unknown --toolchain nightly +$ cargo install wasm-pack ``` -Move to wasm sources folder: +Make sure the crate's tests pass: ``` $ cd wasm-mappings/ +$ cargo test ``` -Make sure the crate's tests pass: +Then rebuild the shipped artifacts: ``` -$ cargo test +$ ./build.sh ``` -Ensure that you have the following wasm post-processing tools installed: +This writes five files into `lib/`: -- `wasm-nm`: https://github.com/fitzgen/wasm-nm -- `wasm-gc`: https://github.com/alexcrichton/wasm-gc -- `wasm-snip`: https://github.com/fitzgen/wasm-snip -- `wasm-opt`: https://github.com/WebAssembly/binaryen +| File | Purpose | +| ----------------------------- | -------------------------------------------- | +| `mappings.wasm` | the WebAssembly module itself | +| `mappings-glue.js` | `wasm-bindgen` glue for Node (CommonJS) | +| `mappings-glue.d.ts` | types for the above node glue file | +| `mappings-glue-browser.mjs` | `wasm-bindgen` glue for browsers (ES module) | +| `mappings-glue-browser.d.mts` | types for the above browser glue file | -(These dependencies should automatically be installed by cargo) +All five are generated and committed; do not edit them by hand. `package.json`'s +`browser` field swaps `lib/read-wasm.js` for `lib/read-wasm-browser.js`, which +is what selects between the Node and browser glue. -Build Rust crate as a `.wasm` file: +Set `PROFILING=1` to enable the crate's `profiling` feature, which wraps each +query in a `console.time` / `console.timeEnd` pair: ``` -$ cd source-map-mappings-wasm-api/ -$ ./build.py -o ../../lib/mappings.wasm +$ PROFILING=1 ./build.sh ``` -See further information in [wasm-mappings/CONTRIBUTING.md]. +See further information in [wasm-mappings/CONTRIBUTING.md](wasm-mappings/CONTRIBUTING.md). diff --git a/lib/mappings-glue-browser.d.mts b/lib/mappings-glue-browser.d.mts new file mode 100644 index 00000000..d3d1c750 --- /dev/null +++ b/lib/mappings-glue-browser.d.mts @@ -0,0 +1,97 @@ +/* tslint:disable */ +/* eslint-disable */ + +/** + * A parsed `mappings` string, ready to be queried. + * + * JS owns this handle and must call `free()` on it when finished. + */ +export class Mappings { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Find all mappings for the given original location and invoke `cb` on + * each of them. + * + * When `has_original_column` is false, `original_column` is ignored and + * every mapping with a matching source and original line is yielded. + */ + allGeneratedLocationsFor(source: number, original_line: number, has_original_column: boolean, original_column: number, cb: any): void; + /** + * Invoke `cb` on each mapping, in order of generated location. + */ + byGeneratedLocation(cb: any): void; + /** + * Invoke `cb` on each mapping that has original location information, in + * order of original location. + */ + byOriginalLocation(cb: any): void; + /** + * Compute column spans for the mappings. + */ + computeColumnSpans(): void; + /** + * Find the mapping for the given original location, if any exists, and + * invoke `cb` with it once. + */ + generatedLocationFor(source: number, original_line: number, original_column: number, bias: number, cb: any): void; + /** + * Find the mapping for the given generated location, if any exists, and + * invoke `cb` with it once. + */ + originalLocationFor(generated_line: number, generated_column: number, bias: number, cb: any): void; +} + +/** + * Parse a source map's `mappings` string. + * + * On failure, rejects with the numeric `source_map_mappings::Error` code. + * Replaces the old `allocate_mappings` / `parse_mappings` / `get_last_error` + * trio: `wasm-bindgen` copies the string into wasm memory itself, so JS no + * longer has to hand-manage a buffer. + */ +export function parseMappings(mappings: string): Mappings; + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly __wbg_mappings_free: (a: number, b: number) => void; + readonly mappings_allGeneratedLocationsFor: (a: number, b: number, c: number, d: number, e: number, f: any) => [number, number]; + readonly mappings_byGeneratedLocation: (a: number, b: any) => [number, number]; + readonly mappings_byOriginalLocation: (a: number, b: any) => [number, number]; + readonly mappings_computeColumnSpans: (a: number) => void; + readonly mappings_generatedLocationFor: (a: number, b: number, c: number, d: number, e: number, f: any) => [number, number]; + readonly mappings_originalLocationFor: (a: number, b: number, c: number, d: number, e: any) => [number, number]; + readonly parseMappings: (a: number, b: number) => [number, number, number]; + readonly __wbindgen_exn_store: (a: number) => void; + readonly __externref_table_alloc: () => number; + readonly __wbindgen_externrefs: WebAssembly.Table; + readonly __externref_table_dealloc: (a: number) => void; + readonly __wbindgen_malloc: (a: number, b: number) => number; + readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_start: () => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; + +/** + * Instantiates the given `module`, which can either be bytes or + * a precompiled `WebAssembly.Module`. + * + * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. + * + * @returns {InitOutput} + */ +export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; + +/** + * If `module_or_path` is {RequestInfo} or {URL}, makes a request and + * for everything else, calls `WebAssembly.instantiate` directly. + * + * @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. + * + * @returns {Promise} + */ +export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; diff --git a/lib/mappings-glue-browser.mjs b/lib/mappings-glue-browser.mjs new file mode 100644 index 00000000..c10eb288 --- /dev/null +++ b/lib/mappings-glue-browser.mjs @@ -0,0 +1,349 @@ +/* @ts-self-types="./mappings-glue-browser.d.mts" */ + +/** + * A parsed `mappings` string, ready to be queried. + * + * JS owns this handle and must call `free()` on it when finished. + */ +export class Mappings { + static __wrap(ptr) { + const obj = Object.create(Mappings.prototype); + obj.__wbg_ptr = ptr; + MappingsFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + MappingsFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_mappings_free(ptr, 0); + } + /** + * Find all mappings for the given original location and invoke `cb` on + * each of them. + * + * When `has_original_column` is false, `original_column` is ignored and + * every mapping with a matching source and original line is yielded. + * @param {number} source + * @param {number} original_line + * @param {boolean} has_original_column + * @param {number} original_column + * @param {any} cb + */ + allGeneratedLocationsFor(source, original_line, has_original_column, original_column, cb) { + const ret = wasm.mappings_allGeneratedLocationsFor(this.__wbg_ptr, source, original_line, has_original_column, original_column, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } + /** + * Invoke `cb` on each mapping, in order of generated location. + * @param {any} cb + */ + byGeneratedLocation(cb) { + const ret = wasm.mappings_byGeneratedLocation(this.__wbg_ptr, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } + /** + * Invoke `cb` on each mapping that has original location information, in + * order of original location. + * @param {any} cb + */ + byOriginalLocation(cb) { + const ret = wasm.mappings_byOriginalLocation(this.__wbg_ptr, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } + /** + * Compute column spans for the mappings. + */ + computeColumnSpans() { + wasm.mappings_computeColumnSpans(this.__wbg_ptr); + } + /** + * Find the mapping for the given original location, if any exists, and + * invoke `cb` with it once. + * @param {number} source + * @param {number} original_line + * @param {number} original_column + * @param {number} bias + * @param {any} cb + */ + generatedLocationFor(source, original_line, original_column, bias, cb) { + const ret = wasm.mappings_generatedLocationFor(this.__wbg_ptr, source, original_line, original_column, bias, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } + /** + * Find the mapping for the given generated location, if any exists, and + * invoke `cb` with it once. + * @param {number} generated_line + * @param {number} generated_column + * @param {number} bias + * @param {any} cb + */ + originalLocationFor(generated_line, generated_column, bias, cb) { + const ret = wasm.mappings_originalLocationFor(this.__wbg_ptr, generated_line, generated_column, bias, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } +} +if (Symbol.dispose) Mappings.prototype[Symbol.dispose] = Mappings.prototype.free; + +/** + * Parse a source map's `mappings` string. + * + * On failure, rejects with the numeric `source_map_mappings::Error` code. + * Replaces the old `allocate_mappings` / `parse_mappings` / `get_last_error` + * trio: `wasm-bindgen` copies the string into wasm memory itself, so JS no + * longer has to hand-manage a buffer. + * @param {string} mappings + * @returns {Mappings} + */ +export function parseMappings(mappings) { + const ptr0 = passStringToWasm0(mappings, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.parseMappings(ptr0, len0); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + return Mappings.__wrap(ret[0]); +} +function __wbg_get_imports() { + const import0 = { + __proto__: null, + __wbg___wbindgen_throw_5d9e815e6fdf150f: function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }, + __wbg_call_3434fc50d361c5d3: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11) { + arg0.call(arg1, arg2 >>> 0, arg3 >>> 0, arg4 !== 0, arg5 >>> 0, arg6 !== 0, arg7 >>> 0, arg8 >>> 0, arg9 >>> 0, arg10 !== 0, arg11 >>> 0); + }, arguments); }, + __wbindgen_generic_0000000000000001: function(arg0) { + // Cast intrinsic for `F64 -> Externref`. + const ret = arg0; + return ret; + }, + __wbindgen_init_externref_table: function() { + const table = wasm.__wbindgen_externrefs; + const offset = table.grow(4); + table.set(0, undefined); + table.set(offset + 0, undefined); + table.set(offset + 1, null); + table.set(offset + 2, true); + table.set(offset + 3, false); + }, + }; + return { + __proto__: null, + "./mappings_bg.js": import0, + }; +} + +const MappingsFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_mappings_free(ptr, 1)); + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_externrefs.set(idx, obj); + return idx; +} + +function getStringFromWasm0(ptr, len) { + return decodeText(ptr >>> 0, len); +} + +let cachedUint8ArrayMemory0 = null; +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + const idx = addToExternrefTable0(e); + wasm.__wbindgen_exn_store(idx); + } +} + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = cachedTextEncoder.encodeInto(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_externrefs.get(idx); + wasm.__externref_table_dealloc(idx); + return value; +} + +let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); +cachedTextDecoder.decode(); +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +const cachedTextEncoder = new TextEncoder(); + +if (!('encodeInto' in cachedTextEncoder)) { + cachedTextEncoder.encodeInto = function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; + }; +} + +let WASM_VECTOR_LEN = 0; + +let wasmModule, wasmInstance, wasm; +function __wbg_finalize_init(instance, module) { + wasmInstance = instance; + wasm = instance.exports; + wasmModule = module; + cachedUint8ArrayMemory0 = null; + wasm.__wbindgen_start(); + return wasm; +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (!module.ok) { + throw new Error(`failed to fetch Wasm: ${module.status} ${module.statusText} fetching '${module.url}'`); + } + + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + } catch (e) { + const validResponse = expectedResponseType(module.type); + + if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { throw e; } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + } else { + return instance; + } + } + + function expectedResponseType(type) { + switch (type) { + case 'basic': case 'cors': case 'default': return true; + } + return false; + } +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + + if (module !== undefined) { + if (Object.getPrototypeOf(module) === Object.prototype) { + ({module} = module) + } else { + console.warn('using deprecated parameters for `initSync()`; pass a single object instead') + } + } + + const imports = __wbg_get_imports(); + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + const instance = new WebAssembly.Instance(module, imports); + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(module_or_path) { + if (wasm !== undefined) return wasm; + + + if (module_or_path !== undefined) { + if (Object.getPrototypeOf(module_or_path) === Object.prototype) { + ({module_or_path} = module_or_path) + } else { + console.warn('using deprecated parameters for the initialization function; pass a single object instead') + } + } + + if (module_or_path === undefined) { + module_or_path = new URL('mappings.wasm', import.meta.url); + } + const imports = __wbg_get_imports(); + + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); + } + + const { instance, module } = await __wbg_load(await module_or_path, imports); + + return __wbg_finalize_init(instance, module); +} + +export { initSync, __wbg_init as default }; diff --git a/lib/mappings-glue.d.ts b/lib/mappings-glue.d.ts new file mode 100644 index 00000000..b060c57a --- /dev/null +++ b/lib/mappings-glue.d.ts @@ -0,0 +1,54 @@ +/* tslint:disable */ +/* eslint-disable */ + +/** + * A parsed `mappings` string, ready to be queried. + * + * JS owns this handle and must call `free()` on it when finished. + */ +export class Mappings { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Find all mappings for the given original location and invoke `cb` on + * each of them. + * + * When `has_original_column` is false, `original_column` is ignored and + * every mapping with a matching source and original line is yielded. + */ + allGeneratedLocationsFor(source: number, original_line: number, has_original_column: boolean, original_column: number, cb: any): void; + /** + * Invoke `cb` on each mapping, in order of generated location. + */ + byGeneratedLocation(cb: any): void; + /** + * Invoke `cb` on each mapping that has original location information, in + * order of original location. + */ + byOriginalLocation(cb: any): void; + /** + * Compute column spans for the mappings. + */ + computeColumnSpans(): void; + /** + * Find the mapping for the given original location, if any exists, and + * invoke `cb` with it once. + */ + generatedLocationFor(source: number, original_line: number, original_column: number, bias: number, cb: any): void; + /** + * Find the mapping for the given generated location, if any exists, and + * invoke `cb` with it once. + */ + originalLocationFor(generated_line: number, generated_column: number, bias: number, cb: any): void; +} + +/** + * Parse a source map's `mappings` string. + * + * On failure, rejects with the numeric `source_map_mappings::Error` code. + * Replaces the old `allocate_mappings` / `parse_mappings` / `get_last_error` + * trio: `wasm-bindgen` copies the string into wasm memory itself, so JS no + * longer has to hand-manage a buffer. + */ +export function parseMappings(mappings: string): Mappings; diff --git a/lib/mappings-glue.js b/lib/mappings-glue.js new file mode 100644 index 00000000..e26cc87f --- /dev/null +++ b/lib/mappings-glue.js @@ -0,0 +1,253 @@ +/* @ts-self-types="./mappings-glue.d.ts" */ + +/** + * A parsed `mappings` string, ready to be queried. + * + * JS owns this handle and must call `free()` on it when finished. + */ +class Mappings { + static __wrap(ptr) { + const obj = Object.create(Mappings.prototype); + obj.__wbg_ptr = ptr; + MappingsFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + MappingsFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_mappings_free(ptr, 0); + } + /** + * Find all mappings for the given original location and invoke `cb` on + * each of them. + * + * When `has_original_column` is false, `original_column` is ignored and + * every mapping with a matching source and original line is yielded. + * @param {number} source + * @param {number} original_line + * @param {boolean} has_original_column + * @param {number} original_column + * @param {any} cb + */ + allGeneratedLocationsFor(source, original_line, has_original_column, original_column, cb) { + const ret = wasm.mappings_allGeneratedLocationsFor(this.__wbg_ptr, source, original_line, has_original_column, original_column, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } + /** + * Invoke `cb` on each mapping, in order of generated location. + * @param {any} cb + */ + byGeneratedLocation(cb) { + const ret = wasm.mappings_byGeneratedLocation(this.__wbg_ptr, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } + /** + * Invoke `cb` on each mapping that has original location information, in + * order of original location. + * @param {any} cb + */ + byOriginalLocation(cb) { + const ret = wasm.mappings_byOriginalLocation(this.__wbg_ptr, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } + /** + * Compute column spans for the mappings. + */ + computeColumnSpans() { + wasm.mappings_computeColumnSpans(this.__wbg_ptr); + } + /** + * Find the mapping for the given original location, if any exists, and + * invoke `cb` with it once. + * @param {number} source + * @param {number} original_line + * @param {number} original_column + * @param {number} bias + * @param {any} cb + */ + generatedLocationFor(source, original_line, original_column, bias, cb) { + const ret = wasm.mappings_generatedLocationFor(this.__wbg_ptr, source, original_line, original_column, bias, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } + /** + * Find the mapping for the given generated location, if any exists, and + * invoke `cb` with it once. + * @param {number} generated_line + * @param {number} generated_column + * @param {number} bias + * @param {any} cb + */ + originalLocationFor(generated_line, generated_column, bias, cb) { + const ret = wasm.mappings_originalLocationFor(this.__wbg_ptr, generated_line, generated_column, bias, cb); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } + } +} +if (Symbol.dispose) Mappings.prototype[Symbol.dispose] = Mappings.prototype.free; +exports.Mappings = Mappings; + +/** + * Parse a source map's `mappings` string. + * + * On failure, rejects with the numeric `source_map_mappings::Error` code. + * Replaces the old `allocate_mappings` / `parse_mappings` / `get_last_error` + * trio: `wasm-bindgen` copies the string into wasm memory itself, so JS no + * longer has to hand-manage a buffer. + * @param {string} mappings + * @returns {Mappings} + */ +function parseMappings(mappings) { + const ptr0 = passStringToWasm0(mappings, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.parseMappings(ptr0, len0); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + return Mappings.__wrap(ret[0]); +} +exports.parseMappings = parseMappings; +function __wbg_get_imports() { + const import0 = { + __proto__: null, + __wbg___wbindgen_throw_5d9e815e6fdf150f: function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }, + __wbg_call_3434fc50d361c5d3: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11) { + arg0.call(arg1, arg2 >>> 0, arg3 >>> 0, arg4 !== 0, arg5 >>> 0, arg6 !== 0, arg7 >>> 0, arg8 >>> 0, arg9 >>> 0, arg10 !== 0, arg11 >>> 0); + }, arguments); }, + __wbindgen_generic_0000000000000001: function(arg0) { + // Cast intrinsic for `F64 -> Externref`. + const ret = arg0; + return ret; + }, + __wbindgen_init_externref_table: function() { + const table = wasm.__wbindgen_externrefs; + const offset = table.grow(4); + table.set(0, undefined); + table.set(offset + 0, undefined); + table.set(offset + 1, null); + table.set(offset + 2, true); + table.set(offset + 3, false); + }, + }; + return { + __proto__: null, + "./mappings_bg.js": import0, + }; +} + +const MappingsFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_mappings_free(ptr, 1)); + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_externrefs.set(idx, obj); + return idx; +} + +function getStringFromWasm0(ptr, len) { + return decodeText(ptr >>> 0, len); +} + +let cachedUint8ArrayMemory0 = null; +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + const idx = addToExternrefTable0(e); + wasm.__wbindgen_exn_store(idx); + } +} + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = cachedTextEncoder.encodeInto(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_externrefs.get(idx); + wasm.__externref_table_dealloc(idx); + return value; +} + +let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); +cachedTextDecoder.decode(); +function decodeText(ptr, len) { + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +const cachedTextEncoder = new TextEncoder(); + +if (!('encodeInto' in cachedTextEncoder)) { + cachedTextEncoder.encodeInto = function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; + }; +} + +let WASM_VECTOR_LEN = 0; + +const wasmPath = `${__dirname}/mappings.wasm`; +const wasmBytes = require('fs').readFileSync(wasmPath); +const wasmModule = new WebAssembly.Module(wasmBytes); +let wasmInstance = new WebAssembly.Instance(wasmModule, __wbg_get_imports()); +let wasm = wasmInstance.exports; +wasm.__wbindgen_start(); diff --git a/lib/mappings.wasm b/lib/mappings.wasm index cdcc2958c0f445a3662c9a82a0eead47e8210c3e..2543cd1e759ba72bc582b52a291323f8141cc8d5 100644 GIT binary patch literal 28556 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

(!GnJa-- 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]g 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 Oz59N9<>Hl#EB_z0Xo+P2 diff --git a/lib/read-wasm-browser.js b/lib/read-wasm-browser.js index a4fb29c2..c7e13b3b 100644 --- a/lib/read-wasm-browser.js +++ b/lib/read-wasm-browser.js @@ -1,21 +1,38 @@ "use strict"; let mappingsWasm = null; +let cachedGlue = null; module.exports = function readWasm() { - if (typeof mappingsWasm === "string") { - return fetch(mappingsWasm).then(response => response.arrayBuffer()); + if ( + typeof mappingsWasm !== "string" && + !(mappingsWasm instanceof ArrayBuffer) + ) { + throw new Error( + "You must provide the string URL or ArrayBuffer contents " + + "of lib/mappings.wasm by calling " + + "SourceMapConsumer.initialize({ 'lib/mappings.wasm': ... }) " + + "before using SourceMapConsumer" + ); } - if (mappingsWasm instanceof ArrayBuffer) { - return Promise.resolve(mappingsWasm); + + if (cachedGlue) { + return cachedGlue; } - throw new Error( - "You must provide the string URL or ArrayBuffer contents " + - "of lib/mappings.wasm by calling " + - "SourceMapConsumer.initialize({ 'lib/mappings.wasm': ... }) " + - "before using SourceMapConsumer" - ); + // The browser glue is an ES module; `import()` keeps this file loadable as + // CommonJS. `default` is wasm-bindgen's async init, which accepts either a + // URL to fetch or the module bytes directly. + cachedGlue = import("./mappings-glue-browser.mjs") + .then(glue => + glue.default({ module_or_path: mappingsWasm }).then(() => glue) + ) + .then(null, e => { + cachedGlue = null; + throw e; + }); + + return cachedGlue; }; module.exports.initialize = input => { diff --git a/lib/read-wasm.js b/lib/read-wasm.js index 2ce01a75..72afb6f7 100644 --- a/lib/read-wasm.js +++ b/lib/read-wasm.js @@ -3,21 +3,10 @@ // Note: This file is replaced with "read-wasm-browser.js" when this module is // bundled with a packager that takes package.json#browser fields into account. -const fs = require("fs"); -const path = require("path"); - module.exports = function readWasm() { - return new Promise((resolve, reject) => { - const wasmPath = path.join(__dirname, "mappings.wasm"); - fs.readFile(wasmPath, null, (error, data) => { - if (error) { - reject(error); - return; - } - - resolve(data.buffer); - }); - }); + // The generated Node glue reads `mappings.wasm` off disk and instantiates it + // itself, so requiring it lazily here is all the loading we need to do. + return Promise.resolve(require("./mappings-glue.js")); }; module.exports.initialize = _ => { diff --git a/lib/source-map-consumer.js b/lib/source-map-consumer.js index 7381a668..17ef92b1 100644 --- a/lib/source-map-consumer.js +++ b/lib/source-map-consumer.js @@ -223,7 +223,7 @@ class BasicSourceMapConsumer extends SourceMapConsumer { that.x_google_ignoreList = x_google_ignoreList; that._computedColumnSpans = false; - that._mappingsPtr = 0; + that._wasmMappings = null; that._wasm = null; return wasm().then(w => { @@ -290,12 +290,12 @@ class BasicSourceMapConsumer extends SourceMapConsumer { return this._absoluteSources.toArray(); } - _getMappingsPtr() { - if (this._mappingsPtr === 0) { + _getWasmMappings() { + if (this._wasmMappings === null) { this._parseMappings(); } - return this._mappingsPtr; + return this._wasmMappings; } /** @@ -304,25 +304,10 @@ class BasicSourceMapConsumer extends SourceMapConsumer { * `this.__originalMappings` properties). */ _parseMappings() { - const aStr = this._mappings; - const size = aStr.length; - - // Interpret signed result of allocate_mappings as unsigned, otherwise - // addresses higher than 2GB will be negative. - const mappingsBufPtr = this._wasm.exports.allocate_mappings(size) >>> 0; - const mappingsBuf = new Uint8Array( - this._wasm.exports.memory.buffer, - mappingsBufPtr, - size - ); - for (let i = 0; i < size; i++) { - mappingsBuf[i] = aStr.charCodeAt(i); - } - - const mappingsPtr = this._wasm.exports.parse_mappings(mappingsBufPtr); - - if (!mappingsPtr) { - const error = this._wasm.exports.get_last_error(); + let mappings; + try { + mappings = this._wasm.parseMappings(this._mappings); + } catch (error) { let msg = `Error parsing mappings (code ${error}): `; // XXX: keep these error codes in sync with `wasm-mappings`. @@ -348,41 +333,38 @@ class BasicSourceMapConsumer extends SourceMapConsumer { throw new Error(msg); } - this._mappingsPtr = mappingsPtr; + this._wasmMappings = mappings; } eachMapping(aCallback, aContext, aOrder) { const context = aContext || null; const order = aOrder || SourceMapConsumer.GENERATED_ORDER; - this._wasm.withMappingCallback( - mapping => { - if (mapping.source !== null) { - mapping.source = this._absoluteSources.at(mapping.source); - - if (mapping.name !== null) { - mapping.name = this._names.at(mapping.name); - } - } - if (this._computedColumnSpans && mapping.lastGeneratedColumn === null) { - mapping.lastGeneratedColumn = Infinity; - } + const callback = wasm.mappingCallback(mapping => { + if (mapping.source !== null) { + mapping.source = this._absoluteSources.at(mapping.source); - aCallback.call(context, mapping); - }, - () => { - switch (order) { - case SourceMapConsumer.GENERATED_ORDER: - this._wasm.exports.by_generated_location(this._getMappingsPtr()); - break; - case SourceMapConsumer.ORIGINAL_ORDER: - this._wasm.exports.by_original_location(this._getMappingsPtr()); - break; - default: - throw new Error("Unknown order of iteration."); + if (mapping.name !== null) { + mapping.name = this._names.at(mapping.name); } } - ); + if (this._computedColumnSpans && mapping.lastGeneratedColumn === null) { + mapping.lastGeneratedColumn = Infinity; + } + + aCallback.call(context, mapping); + }); + + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + this._getWasmMappings().byGeneratedLocation(callback); + break; + case SourceMapConsumer.ORIGINAL_ORDER: + this._getWasmMappings().byOriginalLocation(callback); + break; + default: + throw new Error("Unknown order of iteration."); + } } allGeneratedPositionsFor(aArgs) { @@ -405,8 +387,12 @@ class BasicSourceMapConsumer extends SourceMapConsumer { const mappings = []; - this._wasm.withMappingCallback( - m => { + this._getWasmMappings().allGeneratedLocationsFor( + source, + originalLine - 1, + "column" in aArgs, + originalColumn, + wasm.mappingCallback(m => { let lastColumn = m.lastGeneratedColumn; if (this._computedColumnSpans && lastColumn === null) { lastColumn = Infinity; @@ -416,25 +402,16 @@ class BasicSourceMapConsumer extends SourceMapConsumer { column: m.generatedColumn, lastColumn, }); - }, - () => { - this._wasm.exports.all_generated_locations_for( - this._getMappingsPtr(), - source, - originalLine - 1, - "column" in aArgs, - originalColumn - ); - } + }) ); return mappings; } destroy() { - if (this._mappingsPtr !== 0) { - this._wasm.exports.free_mappings(this._mappingsPtr); - this._mappingsPtr = 0; + if (this._wasmMappings !== null) { + this._wasmMappings.free(); + this._wasmMappings = null; } } @@ -447,7 +424,7 @@ class BasicSourceMapConsumer extends SourceMapConsumer { return; } - this._wasm.exports.compute_column_spans(this._getMappingsPtr()); + this._getWasmMappings().computeColumnSpans(); this._computedColumnSpans = true; } @@ -499,16 +476,11 @@ class BasicSourceMapConsumer extends SourceMapConsumer { } let mapping; - this._wasm.withMappingCallback( - m => (mapping = m), - () => { - this._wasm.exports.original_location_for( - this._getMappingsPtr(), - needle.generatedLine - 1, - needle.generatedColumn, - bias - ); - } + this._getWasmMappings().originalLocationFor( + needle.generatedLine - 1, + needle.generatedColumn, + bias, + wasm.mappingCallback(m => (mapping = m)) ); if (mapping) { @@ -640,17 +612,12 @@ class BasicSourceMapConsumer extends SourceMapConsumer { } let mapping; - this._wasm.withMappingCallback( - m => (mapping = m), - () => { - this._wasm.exports.generated_location_for( - this._getMappingsPtr(), - needle.source, - needle.originalLine - 1, - needle.originalColumn, - bias - ); - } + this._getWasmMappings().generatedLocationFor( + needle.source, + needle.originalLine - 1, + needle.originalColumn, + bias, + wasm.mappingCallback(m => (mapping = m)) ); if (mapping) { diff --git a/lib/wasm.js b/lib/wasm.js index 3091d9ee..5ff17f33 100644 --- a/lib/wasm.js +++ b/lib/wasm.js @@ -13,6 +13,52 @@ function Mapping() { this.name = null; } +/** + * Wrap a `mapping => {}` callback in the flat-argument form the wasm module + * invokes. Building the `Mapping` here (rather than in Rust) keeps every + * mapping on a single hidden class. + */ +function mappingCallback(callback) { + return function ( + generatedLine, + generatedColumn, + + hasLastGeneratedColumn, + lastGeneratedColumn, + + hasOriginal, + source, + originalLine, + originalColumn, + + hasName, + name + ) { + const mapping = new Mapping(); + // JS uses 1-based line numbers, wasm uses 0-based. + mapping.generatedLine = generatedLine + 1; + mapping.generatedColumn = generatedColumn; + + if (hasLastGeneratedColumn) { + // JS uses inclusive last generated column, wasm uses exclusive. + mapping.lastGeneratedColumn = lastGeneratedColumn - 1; + } + + if (hasOriginal) { + mapping.source = source; + // JS uses 1-based line numbers, wasm uses 0-based. + mapping.originalLine = originalLine + 1; + mapping.originalColumn = originalColumn; + + if (hasName) { + mapping.name = name; + } + } + + callback(mapping); + }; +} + let cachedWasm = null; module.exports = function wasm() { @@ -20,119 +66,12 @@ module.exports = function wasm() { return cachedWasm; } - const callbackStack = []; - - cachedWasm = readWasm() - .then(buffer => { - return WebAssembly.instantiate(buffer, { - env: { - mapping_callback( - generatedLine, - generatedColumn, - - hasLastGeneratedColumn, - lastGeneratedColumn, - - hasOriginal, - source, - originalLine, - originalColumn, - - hasName, - name - ) { - const mapping = new Mapping(); - // JS uses 1-based line numbers, wasm uses 0-based. - mapping.generatedLine = generatedLine + 1; - mapping.generatedColumn = generatedColumn; - - if (hasLastGeneratedColumn) { - // JS uses inclusive last generated column, wasm uses exclusive. - mapping.lastGeneratedColumn = lastGeneratedColumn - 1; - } - - if (hasOriginal) { - mapping.source = source; - // JS uses 1-based line numbers, wasm uses 0-based. - mapping.originalLine = originalLine + 1; - mapping.originalColumn = originalColumn; - - if (hasName) { - mapping.name = name; - } - } - - callbackStack[callbackStack.length - 1](mapping); - }, - - start_all_generated_locations_for() { - console.time("all_generated_locations_for"); - }, - end_all_generated_locations_for() { - console.timeEnd("all_generated_locations_for"); - }, - - start_compute_column_spans() { - console.time("compute_column_spans"); - }, - end_compute_column_spans() { - console.timeEnd("compute_column_spans"); - }, - - start_generated_location_for() { - console.time("generated_location_for"); - }, - end_generated_location_for() { - console.timeEnd("generated_location_for"); - }, - - start_original_location_for() { - console.time("original_location_for"); - }, - end_original_location_for() { - console.timeEnd("original_location_for"); - }, - - start_parse_mappings() { - console.time("parse_mappings"); - }, - end_parse_mappings() { - console.timeEnd("parse_mappings"); - }, - - start_sort_by_generated_location() { - console.time("sort_by_generated_location"); - }, - end_sort_by_generated_location() { - console.timeEnd("sort_by_generated_location"); - }, - - start_sort_by_original_location() { - console.time("sort_by_original_location"); - }, - end_sort_by_original_location() { - console.timeEnd("sort_by_original_location"); - }, - }, - }); - }) - .then(Wasm => { - return { - exports: Wasm.instance.exports, - withMappingCallback: (mappingCallback, f) => { - callbackStack.push(mappingCallback); - try { - f(); - } finally { - callbackStack.pop(); - } - }, - }; - }) - .then(null, e => { - cachedWasm = null; - throw e; - }); + cachedWasm = readWasm().then(null, e => { + cachedWasm = null; + throw e; + }); return cachedWasm; }; + +module.exports.mappingCallback = mappingCallback; diff --git a/package.json b/package.json index c8dc010b..7b2f9758 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ }, "license": "BSD-3-Clause", "scripts": { - "lint": "eslint --fix *.js lib/ test/ --ignore-pattern 'test/source-map-tests/**'", + "lint": "eslint --fix *.js lib/ test/ --ignore-pattern 'test/source-map-tests/**' --ignore-pattern 'lib/mappings-glue*'", "test": "git submodule update --init --recursive; node test/run-tests.js", "coverage": "c8 --reporter=text --reporter=html npm test", "prettier": "prettier --write .", diff --git a/test/test-source-map-consumer.js b/test/test-source-map-consumer.js index dc40ba28..8cf50988 100644 --- a/test/test-source-map-consumer.js +++ b/test/test-source-map-consumer.js @@ -2143,11 +2143,11 @@ exports["test SourceMapConsumer.with"] = async function (assert) { await new Promise(r => setTimeout(r, 1)); // Should not have parsed and allocated mappings yet. - assert.equal(c._mappingsPtr, 0); + assert.equal(c._wasmMappings, null); // Force the mappings to be parsed and assert that we allocated mappings. c.eachMapping(_ => {}); - assert.ok(c._mappingsPtr != 0); + assert.ok(c._wasmMappings != null); return 6; } @@ -2157,7 +2157,7 @@ exports["test SourceMapConsumer.with"] = async function (assert) { assert.equal(six, 6); // At the end of `with`, we destroyed the mappings. - assert.equal(consumer._mappingsPtr, 0); + assert.equal(consumer._wasmMappings, null); }; exports["test SourceMapConsumer.with and exceptions"] = async function ( @@ -2169,10 +2169,10 @@ exports["test SourceMapConsumer.with and exceptions"] = async function ( try { await SourceMapConsumer.with(util.testMap, null, async function (c) { consumer = c; - assert.equal(c._mappingsPtr, 0); + assert.equal(c._wasmMappings, null); c.eachMapping(_ => {}); - assert.ok(c._mappingsPtr != 0); + assert.ok(c._wasmMappings != null); throw 6; }); @@ -2181,7 +2181,7 @@ exports["test SourceMapConsumer.with and exceptions"] = async function ( } assert.equal(error, 6); - assert.equal(consumer._mappingsPtr, 0); + assert.equal(consumer._wasmMappings, null); }; exports["test a mapping at the boundary of indexed source map offset"] = diff --git a/wasm-mappings/.gitignore b/wasm-mappings/.gitignore index 143b1ca0..48292f4b 100644 --- a/wasm-mappings/.gitignore +++ b/wasm-mappings/.gitignore @@ -1,4 +1,5 @@ /target/ **/*.rs.bk -Cargo.lock +source-map-mappings-wasm-api/pkg-node/ +source-map-mappings-wasm-api/pkg-web/ diff --git a/wasm-mappings/CONTRIBUTING.md b/wasm-mappings/CONTRIBUTING.md index d67cd208..1f54a686 100644 --- a/wasm-mappings/CONTRIBUTING.md +++ b/wasm-mappings/CONTRIBUTING.md @@ -8,28 +8,29 @@ To build the core library for the host target (for use with testing): $ cargo build ``` -To build for WebAssembly, ensure that you have the `wasm32-unknown-unknown` target: +To build the WebAssembly module and its JS glue, use the build script in this +directory: ``` -$ rustup update -$ rustup target add wasm32-unknown-unknown --toolchain nightly +$ ./build.sh ``` -Then, cross compile to a `.wasm` file via the WebAssembly API crate: +That runs [`wasm-pack`](https://rustwasm.github.io/wasm-pack/) twice -- once +for the `nodejs` target and once for `web` -- and installs the results into +`../lib/`. Both targets produce an identical `.wasm`; only the JS glue +differs, and the script fails if they ever diverge. -``` -$ cd source-map-mappings-wasm-api/ -$ ./build.py -o output.wasm -``` +`wasm-pack` is the only tool you need to install: it vendors its own +`wasm-bindgen` and `wasm-opt`. The toolchain version is pinned in +`rust-toolchain.toml`, including the `wasm32-unknown-unknown` target, so +`rustup` will fetch whatever is missing. -The `build.py` script handles shrinking the size of the resulting `.wasm` file -for you, with `wasm-gc`, `wasm-snip`, and `wasm-opt`. +Set `PROFILING=1` to enable the `profiling` cargo feature. -For more details, run: - -``` -$ ./build.py --help -``` +The generated artifacts are committed to the repository, and the `wasm-dist` +CI job rebuilds them and fails if they differ byte-for-byte. If you change +anything under `wasm-mappings/`, re-run `./build.sh` and commit the result in +the same change. ## Testing @@ -41,18 +42,13 @@ $ cargo test ## Automatic code formatting -We use [`rustfmt`](https://github.com/rust-lang-nursery/rustfmt) to enforce a +We use [`rustfmt`](https://github.com/rust-lang/rustfmt) to enforce a consistent code style across the whole code base. -You can install the latest version of `rustfmt` with this command: - ``` -$ rustup update nightly -$ cargo install -f rustfmt-nightly +$ rustup component add rustfmt ``` -Ensure that `~/.cargo/bin` is on your path. - Once that is taken care of, you can (re)format all code by running this command: ``` diff --git a/wasm-mappings/Cargo.lock b/wasm-mappings/Cargo.lock new file mode 100644 index 00000000..d1040f2b --- /dev/null +++ b/wasm-mappings/Cargo.lock @@ -0,0 +1,198 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" +dependencies = [ + "memchr", +] + +[[package]] +name = "env_logger" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" +dependencies = [ + "log 0.3.9", + "regex", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +dependencies = [ + "log 0.4.34", +] + +[[package]] +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "quickcheck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd532ab58d22171f7168ef5a751133566f8fd88d362d12b07a91d8e59e0ff5cb" +dependencies = [ + "env_logger", + "log 0.3.9", + "rand 0.3.23", +] + +[[package]] +name = "rand" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +dependencies = [ + "libc", + "rand 0.4.6", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96f815e01bbd9678b50d927f79aa1cf3ffdfdb1b9787317c1284dadb894ad0e8" +dependencies = [ + "rand_core 0.4.3", +] + +[[package]] +name = "rand_core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e5937858e6fd18cd595d558f90bb5de3b72ae23f9e3763af0e805949b04ef60" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.2", +] + +[[package]] +name = "regex" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", + "utf8-ranges", +] + +[[package]] +name = "regex-syntax" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" +dependencies = [ + "ucd-util", +] + +[[package]] +name = "source-map-mappings" +version = "0.5.0" +dependencies = [ + "quickcheck", + "vlq", +] + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "ucd-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abd2fc5d32b590614af8b0a20d837f32eca055edd0bbead59a9cfe80858be003" + +[[package]] +name = "utf8-ranges" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" + +[[package]] +name = "vlq" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/wasm-mappings/Cargo.toml b/wasm-mappings/Cargo.toml index 6e075f37..869e6517 100644 --- a/wasm-mappings/Cargo.toml +++ b/wasm-mappings/Cargo.toml @@ -21,10 +21,9 @@ repository = "https://github.com/mozilla/source-map" version = "0.5.0" [dependencies] -rand = "0.4.1" vlq = "0.5.1" [dev-dependencies] quickcheck = "0.5.0" [profile.release] -debug = true +debug = false diff --git a/wasm-mappings/build.sh b/wasm-mappings/build.sh new file mode 100755 index 00000000..f7a72b0c --- /dev/null +++ b/wasm-mappings/build.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# +# Build `lib/mappings.wasm` and its wasm-bindgen glue. +# +# Requires `wasm-pack` (https://rustwasm.github.io/wasm-pack/), which vendors +# its own `wasm-bindgen` and `wasm-opt` -- there is nothing else to install. +# +# Two targets are built because the package is CommonJS but also supports +# browsers via `package.json#browser`: +# +# nodejs -> lib/mappings-glue.js (CJS, reads mappings.wasm off disk) +# web -> lib/mappings-glue-browser.mjs (ESM, init() takes a URL or bytes) +# +# Both emit the same `.wasm`; only the glue differs. +# +# Set PROFILING=1 to enable the `profiling` cargo feature. + +set -eu + +cd "$(dirname "$0")" +REPO_ROOT="$(pwd)/.." +CRATE_DIR="source-map-mappings-wasm-api" + +CARGO_ARGS="" +if [ "${PROFILING:-}" = "1" ]; then + CARGO_ARGS="--features profiling" +fi + +cd "$CRATE_DIR" +rm -rf pkg-node pkg-web + +# shellcheck disable=SC2086 +wasm-pack build --release --target nodejs \ + --out-dir pkg-node --out-name mappings --no-pack -- $CARGO_ARGS +# shellcheck disable=SC2086 +wasm-pack build --release --target web \ + --out-dir pkg-web --out-name mappings --no-pack -- $CARGO_ARGS + +# Both targets must agree on the binary; if they ever diverge, shipping one +# `mappings.wasm` for both would be silently wrong. +cmp pkg-node/mappings_bg.wasm pkg-web/mappings_bg.wasm + +LIB="$REPO_ROOT/lib" +cp pkg-node/mappings_bg.wasm "$LIB/mappings.wasm" + +# The glue looks for `mappings_bg.wasm`; we ship it as `mappings.wasm` so the +# URL documented for `SourceMapConsumer.initialize` keeps working. +sed -e "s/mappings_bg\.wasm/mappings.wasm/g" \ + -e 's|"\./mappings\.d\.ts"|"./mappings-glue.d.ts"|' \ + pkg-node/mappings.js > "$LIB/mappings-glue.js" +sed -e "s/mappings_bg\.wasm/mappings.wasm/g" \ + -e 's|"\./mappings\.d\.ts"|"./mappings-glue-browser.d.mts"|' \ + pkg-web/mappings.js > "$LIB/mappings-glue-browser.mjs" + +cp pkg-node/mappings.d.ts "$LIB/mappings-glue.d.ts" +cp pkg-web/mappings.d.ts "$LIB/mappings-glue-browser.d.mts" + +# Nothing should still point at the wasm-pack-internal name. +! grep -q "mappings_bg\.wasm" "$LIB/mappings-glue.js" "$LIB/mappings-glue-browser.mjs" + +echo "built $(wc -c < "$LIB/mappings.wasm") byte lib/mappings.wasm" diff --git a/wasm-mappings/ci/script.sh b/wasm-mappings/ci/script.sh index e59fe4a0..b913f568 100755 --- a/wasm-mappings/ci/script.sh +++ b/wasm-mappings/ci/script.sh @@ -13,10 +13,6 @@ case "$JOB" in rustup target add wasm32-unknown-unknown cd source-map-mappings-wasm-api/ - # Non-release builds are broken for wasm32-unknown-unknown targets right now. - # cargo build --target wasm32-unknown-unknown - # test -f target/wasm32-unknown-unknown/debug/source_map_mappings_wasm_api.wasm - cargo build --release --target wasm32-unknown-unknown test -f target/wasm32-unknown-unknown/release/source_map_mappings_wasm_api.wasm @@ -24,6 +20,20 @@ case "$JOB" in cargo build --release --target wasm32-unknown-unknown --features profiling test -f target/wasm32-unknown-unknown/release/source_map_mappings_wasm_api.wasm ;; + "wasm-dist") + # Rebuild the committed wasm binary and its glue from source and fail + # if anything differs. Without this, the shipped artifacts are never + # checked against the Rust sources they supposedly came from. + rustup target add wasm32-unknown-unknown + ./build.sh + cd .. + git diff --stat --exit-code -- \ + lib/mappings.wasm \ + lib/mappings-glue.js \ + lib/mappings-glue.d.ts \ + lib/mappings-glue-browser.mjs \ + lib/mappings-glue-browser.d.mts + ;; *) echo "Unknown \$JOB = '$JOB'" exit 1 diff --git a/wasm-mappings/rust-toolchain.toml b/wasm-mappings/rust-toolchain.toml new file mode 100644 index 00000000..9ceeb7e5 --- /dev/null +++ b/wasm-mappings/rust-toolchain.toml @@ -0,0 +1,10 @@ +# Pinned so that `lib/mappings.wasm` is byte-reproducible: the `wasm-dist` CI +# job rebuilds the committed binary and fails if it differs, which only works +# if everyone builds with the same rustc. Bump deliberately, and commit the +# regenerated `lib/mappings.wasm` in the same change. +# +# Note: the `cargo.yml` test matrix overrides this via `rustup override set`, +# so stable/beta/nightly coverage is unaffected. +[toolchain] +channel = "1.98.1" +targets = ["wasm32-unknown-unknown"] diff --git a/wasm-mappings/source-map-mappings-wasm-api/Cargo.lock b/wasm-mappings/source-map-mappings-wasm-api/Cargo.lock new file mode 100644 index 00000000..7a1116fd --- /dev/null +++ b/wasm-mappings/source-map-mappings-wasm-api/Cargo.lock @@ -0,0 +1,128 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "source-map-mappings" +version = "0.5.0" +dependencies = [ + "vlq", +] + +[[package]] +name = "source-map-mappings-wasm-api" +version = "0.5.0" +dependencies = [ + "source-map-mappings", + "wasm-bindgen", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "vlq" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff" + +[[package]] +name = "wasm-bindgen" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" +dependencies = [ + "unicode-ident", +] diff --git a/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml b/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml index 43683b01..250d64c4 100644 --- a/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml +++ b/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml @@ -9,6 +9,7 @@ version = "0.5.0" [dependencies] source-map-mappings = { version = "0.5.0", path = ".." } +wasm-bindgen = "0.2" [features] profiling = [] @@ -17,4 +18,8 @@ profiling = [] crate-type = ["cdylib"] [profile.release] -debug = true +debug = false +opt-level = "z" +lto = true +codegen-units = 1 +panic = "abort" diff --git a/wasm-mappings/source-map-mappings-wasm-api/build.py b/wasm-mappings/source-map-mappings-wasm-api/build.py deleted file mode 100755 index 7ff2aab1..00000000 --- a/wasm-mappings/source-map-mappings-wasm-api/build.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import os -import re -import subprocess -import sys - -DESC = """ - -Build, trim, and optimize the `.wasm` file for inclusion in the -`mozilla/source-map` library. - -Requires: - -- wasm-nm: https://github.com/fitzgen/wasm-nm -- wasm-gc: https://github.com/alexcrichton/wasm-gc -- wasm-snip: https://github.com/fitzgen/wasm-snip -- wasm-opt: https://github.com/WebAssembly/binaryen - -""" - -parser = argparse.ArgumentParser( - formatter_class=argparse.RawDescriptionHelpFormatter, - description=DESC) - -parser.add_argument( - "-g", - "--debug", - action="store_true", - help="Include debug info (the \"name\" section) in the final `.wasm` file.") - -parser.add_argument( - "-p", - "--profiling", - action="store_true", - help="Enable the `profiling` cargo feature.") - -parser.add_argument( - "-o", - "--output", - type=str, - default=None, - help="The path to write the output `.wasm` file to. If not supplied, the `.wasm` file is written to `stdout`.") - -parser.add_argument( - "--no-wasm-opt", - dest="wasm_opt", - action="store_false", - help="Do not run `wasm-opt`.") - -parser.add_argument( - "--no-wasm-gc", - dest="wasm_gc", - action="store_false", - help="Do not run `wasm-gc`.") - -parser.add_argument( - "--no-wasm-snip", - dest="wasm_snip", - action="store_false", - help="Do not run `wasm-snip`.") - -def decode(f): - return f.decode(encoding="utf-8", errors="ignore") - -def run(cmd, **kwargs): - sys.stderr.write(str(cmd) + "\n") - - if "stdout" not in kwargs: - kwargs["stdout"] = subprocess.PIPE - child = subprocess.run(cmd, **kwargs) - if child.returncode != 0: - raise Exception("{} did not exit OK".format(str(cmd))) - return decode(child.stdout) - -def add_path_ext_prefix(path, prefix): - (root, ext) = os.path.splitext(path) - return root + "." + prefix + ext - -def build(args): - cmd = ["cargo", "build", "--release", "--target", "wasm32-unknown-unknown"] - if args.profiling: - cmd.extend(["--features", "profiling"]) - run(cmd) - return "./target/wasm32-unknown-unknown/release/source_map_mappings_wasm_api.wasm" - -def wasm_gc(args, wasm_path): - if not args.wasm_gc: - return wasm_path - - out_path = add_path_ext_prefix(wasm_path, "gc") - run(["wasm-gc", wasm_path, out_path]) - return out_path - -SHOULD_SNIP = [ - re.compile(r".*(std|core)(9|::)panicking.*"), - re.compile(r".*(std|core)(3|::)fmt.*"), - re.compile(r".*core(6|::)option(13|::)expect_failed.*"), - re.compile(r".*core(5|::)slice(\d+|::)slice_index_.*_fail.*"), - re.compile(r".*core(3|::)str(\d+|::)slice_.*_fail.*"), - re.compile(r".*core(6|::)result(13|::)unwrap_failed.*"), - re.compile(r".*std(6|::)thread(5|::)local.*"), - re.compile(r".*std(2|::)io(5|::).*"), - re.compile(r"__.*2"), - re.compile(r".*(std|core)(5|::)error.*"), - re.compile(r".*(std|core)(3|::)any(3|::)Any.*"), -] - -def wasm_snip(args, wasm_path): - if not args.wasm_snip: - return wasm_path - - out_path = add_path_ext_prefix(wasm_path, "snip") - - private_functions = run(["wasm-nm", "-j", wasm_path]).splitlines() - - snip_functions = set() - for snip in SHOULD_SNIP: - snip_functions.update(filter(lambda f: re.match(snip, f), - private_functions)) - - run(["wasm-snip", "-o", out_path, wasm_path, *snip_functions]), - return out_path - -def wasm_opt(args, wasm_path): - if not args.wasm_opt: - return wasm_path - - out_path = add_path_ext_prefix(wasm_path, "opt") - - cmd = [ - "wasm-opt", - "-O3", - "-Oz", - "--duplicate-function-elimination", - "-o", out_path, - wasm_path - ] - if args.debug: - cmd.append("-g") - run(cmd) - return out_path - -def main(): - args = parser.parse_args() - os.chdir(os.path.dirname(sys.argv[0])) - - wasm_path = build(args) - wasm_path = wasm_gc(args, wasm_path) - wasm_path = wasm_snip(args, wasm_path) - # GC again after snipping. - wasm_path = wasm_gc(args, wasm_path) - wasm_path = wasm_opt(args, wasm_path) - - if args.output: - run(["cp", wasm_path, args.output]) - else: - run(["cat", wasm_path], stdout=subprocess.STDOUT) - -if __name__ == "__main__": - main() diff --git a/wasm-mappings/source-map-mappings-wasm-api/src/lib.rs b/wasm-mappings/source-map-mappings-wasm-api/src/lib.rs index d91ed381..c669a5f2 100644 --- a/wasm-mappings/source-map-mappings-wasm-api/src/lib.rs +++ b/wasm-mappings/source-map-mappings-wasm-api/src/lib.rs @@ -1,54 +1,43 @@ //! The public JS API to the `source-map-mappings` crate. //! -//! ## Usage +//! This is a `wasm-bindgen` module. JS obtains a `Mappings` handle from +//! `parseMappings`, queries it, and calls `free()` on it when finished. //! -//! 1. Instantiate the WebAssembly module, supplying a JS implementation of -//! `mapping_callback`. -//! -//! 2. Allocate space for the mappings string with `allocate_mappings`. -//! -//! 3. Initialize the mappings string by copying the JS `String`'s data into it. -//! -//! 4. Parse the mappings with `parse_mappings`. Handle errors, if any. -//! -//! 5. Query the resulting `Mappings` structure as needed with -//! `by_generated_location`, `by_original_location`, `compute_column_spans`, -//! `original_location_for`, `generated_location_for`, and -//! `all_generated_locations_for` as needed. -//! -//! 6. When finished with `Mappings` structure, dispose of it with -//! `free_mappings`. - -// NB: every exported function must be `#[no_mangle]` and `pub extern "C"`. +//! Query methods that yield mappings take a `MappingCallback` -- a JS function +//! invoked once per mapping with a flat list of primitives. Passing the +//! callback per-call (rather than as a single module-level import) is what +//! lets JS avoid maintaining a stack of "currently active" callbacks. #![deny(missing_docs)] extern crate source_map_mappings; +extern crate wasm_bindgen; -use source_map_mappings::{Bias, Error, Mapping, Mappings}; -use std::mem; -use std::ptr; +use source_map_mappings::{Bias, Mapping}; use std::process; -use std::slice; +use wasm_bindgen::prelude::*; #[cfg(feature = "profiling")] mod observer { - use source_map_mappings; + use wasm_bindgen::prelude::*; + + #[wasm_bindgen] + extern "C" { + #[wasm_bindgen(js_namespace = console)] + fn time(label: &str); + #[wasm_bindgen(js_namespace = console, js_name = timeEnd)] + fn time_end(label: &str); + } macro_rules! define_raii_observer { - ( $name:ident , $ctor:ident , $dtor:ident ) => { + ( $name:ident , $label:expr ) => { #[derive(Debug)] pub struct $name; impl Default for $name { #[inline] fn default() -> $name { - extern "C" { - fn $ctor(); - } - unsafe { - $ctor(); - } + time($label); $name } } @@ -56,48 +45,19 @@ mod observer { impl Drop for $name { #[inline] fn drop(&mut self) { - extern "C" { - fn $dtor(); - } - unsafe { - $dtor(); - } + time_end($label); } } - } + }; } - define_raii_observer!(ParseMappings, start_parse_mappings, end_parse_mappings); - define_raii_observer!( - SortByOriginalLocation, - start_sort_by_original_location, - end_sort_by_original_location - ); - define_raii_observer!( - SortByGeneratedLocation, - start_sort_by_generated_location, - end_sort_by_generated_location - ); - define_raii_observer!( - ComputeColumnSpans, - start_compute_column_spans, - end_compute_column_spans - ); - define_raii_observer!( - OriginalLocationFor, - start_original_location_for, - end_original_location_for - ); - define_raii_observer!( - GeneratedLocationFor, - start_generated_location_for, - end_generated_location_for - ); - define_raii_observer!( - AllGeneratedLocationsFor, - start_all_generated_locations_for, - end_all_generated_locations_for - ); + define_raii_observer!(ParseMappings, "parse_mappings"); + define_raii_observer!(SortByOriginalLocation, "sort_by_original_location"); + define_raii_observer!(SortByGeneratedLocation, "sort_by_generated_location"); + define_raii_observer!(ComputeColumnSpans, "compute_column_spans"); + define_raii_observer!(OriginalLocationFor, "original_location_for"); + define_raii_observer!(GeneratedLocationFor, "generated_location_for"); + define_raii_observer!(AllGeneratedLocationsFor, "all_generated_locations_for"); #[derive(Debug, Default)] pub struct Observer; @@ -115,201 +75,71 @@ mod observer { #[cfg(not(feature = "profiling"))] mod observer { + /// No-op observer used when the `profiling` feature is disabled. pub type Observer = (); } use observer::Observer; -static mut LAST_ERROR: Option = None; - -/// Get the last error's error code, or 0 if there was none. -/// -/// See `source_map_mappings::Error` for the error code definitions. -#[no_mangle] -pub extern "C" fn get_last_error() -> u32 { - unsafe { - match LAST_ERROR { - None => 0, - Some(e) => e as u32, - } - } -} - -#[inline] -fn assert_pointer_is_word_aligned(p: *mut u8) { - debug_assert_eq!(p as usize & (mem::size_of::() - 1), 0); -} - -/// Allocate space for a mappings string of the given size (in bytes). -/// -/// It is the JS callers responsibility to initialize the resulting buffer by -/// copying the JS `String` holding the source map's "mappings" into it (encoded -/// in ascii). -#[no_mangle] -pub extern "C" fn allocate_mappings(size: usize) -> *mut u8 { - // Make sure that we don't lose any bytes from size in the remainder. - let size_in_units_of_usize = (size + mem::size_of::() - 1) / mem::size_of::(); - - // Make room for two additional `usize`s: we'll stuff capacity and length in - // there. - let mut vec: Vec = Vec::with_capacity(size_in_units_of_usize + 2); - - // And do the stuffing. - let capacity = vec.capacity(); - vec.push(capacity); - vec.push(size); - - // Leak the vec's elements and get a pointer to them. - let ptr = vec.as_mut_ptr(); - debug_assert!(!ptr.is_null()); - mem::forget(vec); - - // Advance the pointer past our stuffed data and return it to JS, so that JS - // can write the mappings string into it. - let ptr = ptr.wrapping_offset(2) as *mut u8; - assert_pointer_is_word_aligned(ptr); - ptr -} - -#[inline] -fn constrain<'a, T>(_scope: &'a (), reference: &'a T) -> &'a T -where - T: ?Sized, -{ - reference -} - -/// Parse the given initialized mappings string into a `Mappings` structure. -/// -/// Returns `NULL` on failure, or a pointer to the parsed `Mappings` structure -/// on success. -/// -/// In the case of failure, the error can be retrieved with `get_last_error`. -/// -/// In the case of success, the caller takes ownership of the result, and must -/// call `free_mappings` to destroy it when finished. -/// -/// In both the success or failure cases, the caller gives up ownership of the -/// input mappings string and must not use it again. -#[no_mangle] -pub extern "C" fn parse_mappings(mappings: *mut u8) -> *mut Mappings { - assert_pointer_is_word_aligned(mappings); - let mappings = mappings as *mut usize; - - // Unstuff the data we put just before the pointer to the mappings - // string. - let capacity_ptr = mappings.wrapping_offset(-2); - debug_assert!(!capacity_ptr.is_null()); - let capacity = unsafe { *capacity_ptr }; - - let size_ptr = mappings.wrapping_offset(-1); - debug_assert!(!size_ptr.is_null()); - let size = unsafe { *size_ptr }; - - // Construct the input slice from the pointer and parse the mappings. - let result = unsafe { - let input = slice::from_raw_parts(mappings as *const u8, size); - let this_scope = (); - let input = constrain(&this_scope, input); - source_map_mappings::parse_mappings(input) - }; - - // Deallocate the mappings string and its two prefix words. - let size_in_usizes = (size + mem::size_of::() - 1) / mem::size_of::(); - unsafe { - Vec::::from_raw_parts(capacity_ptr, size_in_usizes + 2, capacity); - } - - // Return the result, saving any errors on the side for later inspection by - // JS if required. - match result { - Ok(mappings) => Box::into_raw(Box::new(mappings)), - Err(e) => { - unsafe { - LAST_ERROR = Some(e); - } - ptr::null_mut() - } - } -} - -/// Destroy the given `Mappings` structure. -/// -/// The caller gives up ownership of the mappings and must not use them again. -#[no_mangle] -pub extern "C" fn free_mappings(mappings: *mut Mappings) { - unsafe { - Box::from_raw(mappings); - } -} - -#[inline] -unsafe fn mappings_mut<'a>( - _scope: &'a (), - mappings: *mut Mappings, -) -> &'a mut Mappings { - mappings.as_mut().unwrap() -} - +#[wasm_bindgen] extern "C" { - fn mapping_callback( - // These two parameters are always valid. + /// A JS function invoked once per mapping. + pub type MappingCallback; + + /// Invoke the callback with a single mapping. + /// + /// `last_generated_column` is only meaningful when + /// `has_last_generated_column`; `source`, `original_line` and + /// `original_column` only when `has_original`; `name` only when + /// `has_name`. + #[wasm_bindgen(method, js_name = call, catch)] + fn invoke( + this: &MappingCallback, + ctx: &JsValue, generated_line: u32, generated_column: u32, - - // The `last_generated_column` parameter is only valid if - // `has_last_generated_column` is `true`. has_last_generated_column: bool, last_generated_column: u32, - - // The `source`, `original_line`, and `original_column` parameters are - // only valid if `has_original` is `true`. has_original: bool, source: u32, original_line: u32, original_column: u32, - - // The `name` parameter is only valid if `has_name` is `true`. has_name: bool, name: u32, - ); + ) -> Result<(), JsValue>; } #[inline] -unsafe fn invoke_mapping_callback(mapping: &Mapping) { - let generated_line = mapping.generated_line; - let generated_column = mapping.generated_column; - +fn emit(cb: &MappingCallback, mapping: &Mapping) -> Result<(), JsValue> { let (has_last_generated_column, last_generated_column) = - if let Some(last_generated_column) = mapping.last_generated_column { - (true, last_generated_column) - } else { - (false, 0) + match mapping.last_generated_column { + Some(c) => (true, c), + None => (false, 0), }; let (has_original, source, original_line, original_column, has_name, name) = - if let Some(original) = mapping.original.as_ref() { - let (has_name, name) = if let Some(name) = original.name { - (true, name) - } else { - (false, 0) - }; - - ( - true, - original.source, - original.original_line, - original.original_column, - has_name, - name, - ) - } else { - (false, 0, 0, 0, false, 0) + match mapping.original.as_ref() { + Some(original) => { + let (has_name, name) = match original.name { + Some(name) => (true, name), + None => (false, 0), + }; + ( + true, + original.source, + original.original_line, + original.original_column, + has_name, + name, + ) + } + None => (false, 0, 0, 0, false, 0), }; - mapping_callback( - generated_line, - generated_column, + cb.invoke( + &JsValue::NULL, + mapping.generated_line, + mapping.generated_column, has_last_generated_column, last_generated_column, has_original, @@ -318,44 +148,7 @@ unsafe fn invoke_mapping_callback(mapping: &Mapping) { original_column, has_name, name, - ); -} - -/// Invoke the `mapping_callback` on each mapping in the given `Mappings` -/// structure, in order of generated location. -#[no_mangle] -pub extern "C" fn by_generated_location(mappings: *mut Mappings) { - let this_scope = (); - let mappings = unsafe { mappings_mut(&this_scope, mappings) }; - - mappings - .by_generated_location() - .iter() - .for_each(|m| unsafe { - invoke_mapping_callback(m); - }); -} - -/// Compute column spans for the given mappings. -#[no_mangle] -pub extern "C" fn compute_column_spans(mappings: *mut Mappings) { - let this_scope = (); - let mappings = unsafe { mappings_mut(&this_scope, mappings) }; - - mappings.compute_column_spans(); -} - -/// Invoke the `mapping_callback` on each mapping in the given `Mappings` -/// structure that has original location information, in order of original -/// location. -#[no_mangle] -pub extern "C" fn by_original_location(mappings: *mut Mappings) { - let this_scope = (); - let mappings = unsafe { mappings_mut(&this_scope, mappings) }; - - mappings.by_original_location().for_each(|m| unsafe { - invoke_mapping_callback(m); - }); + ) } #[inline] @@ -363,94 +156,138 @@ fn u32_to_bias(bias: u32) -> Bias { match bias { 1 => Bias::GreatestLowerBound, 2 => Bias::LeastUpperBound, - otherwise => if cfg!(debug_assertions) { - panic!( - "Invalid `Bias = {}`; must be `Bias::GreatestLowerBound = {}` or \ - `Bias::LeastUpperBound = {}`", - otherwise, - Bias::GreatestLowerBound as u32, - Bias::LeastUpperBound as u32, - ) - } else { - process::abort() - }, + otherwise => { + if cfg!(debug_assertions) { + panic!( + "Invalid `Bias = {}`; must be `Bias::GreatestLowerBound = {}` or \ + `Bias::LeastUpperBound = {}`", + otherwise, + Bias::GreatestLowerBound as u32, + Bias::LeastUpperBound as u32, + ) + } else { + process::abort() + } + } } } -/// Find the mapping for the given generated location, if any exists. +/// A parsed `mappings` string, ready to be queried. /// -/// If a mapping is found, the `mapping_callback` is invoked with it -/// once. Otherwise, the `mapping_callback` is not invoked at all. -#[no_mangle] -pub extern "C" fn original_location_for( - mappings: *mut Mappings, - generated_line: u32, - generated_column: u32, - bias: u32, -) { - let this_scope = (); - let mappings = unsafe { mappings_mut(&this_scope, mappings) }; - let bias = u32_to_bias(bias); +/// JS owns this handle and must call `free()` on it when finished. +#[wasm_bindgen] +#[derive(Debug)] +pub struct Mappings { + inner: source_map_mappings::Mappings, +} + +/// Parse a source map's `mappings` string. +/// +/// On failure, rejects with the numeric `source_map_mappings::Error` code. +/// Replaces the old `allocate_mappings` / `parse_mappings` / `get_last_error` +/// trio: `wasm-bindgen` copies the string into wasm memory itself, so JS no +/// longer has to hand-manage a buffer. +#[wasm_bindgen(js_name = parseMappings)] +pub fn parse_mappings(mappings: &str) -> Result { + source_map_mappings::parse_mappings(mappings.as_bytes()) + .map(|inner| Mappings { inner }) + .map_err(|e| JsValue::from(e as u32)) +} - if let Some(m) = mappings.original_location_for(generated_line, generated_column, bias) { - unsafe { - invoke_mapping_callback(m); +#[wasm_bindgen] +impl Mappings { + /// Invoke `cb` on each mapping, in order of generated location. + #[wasm_bindgen(js_name = byGeneratedLocation)] + pub fn by_generated_location(&mut self, cb: &MappingCallback) -> Result<(), JsValue> { + for m in self.inner.by_generated_location().iter() { + emit(cb, m)?; } + Ok(()) } -} -/// Find the mapping for the given original location, if any exists. -/// -/// If a mapping is found, the `mapping_callback` is invoked with it -/// once. Otherwise, the `mapping_callback` is not invoked at all. -#[no_mangle] -pub extern "C" fn generated_location_for( - mappings: *mut Mappings, - source: u32, - original_line: u32, - original_column: u32, - bias: u32, -) { - let this_scope = (); - let mappings = unsafe { mappings_mut(&this_scope, mappings) }; - let bias = u32_to_bias(bias); + /// Invoke `cb` on each mapping that has original location information, in + /// order of original location. + #[wasm_bindgen(js_name = byOriginalLocation)] + pub fn by_original_location(&mut self, cb: &MappingCallback) -> Result<(), JsValue> { + for m in self.inner.by_original_location() { + emit(cb, m)?; + } + Ok(()) + } + + /// Compute column spans for the mappings. + #[wasm_bindgen(js_name = computeColumnSpans)] + pub fn compute_column_spans(&mut self) { + self.inner.compute_column_spans(); + } - if let Some(m) = mappings.generated_location_for(source, original_line, original_column, bias) { - unsafe { - invoke_mapping_callback(m); + /// Find the mapping for the given generated location, if any exists, and + /// invoke `cb` with it once. + #[wasm_bindgen(js_name = originalLocationFor)] + pub fn original_location_for( + &mut self, + generated_line: u32, + generated_column: u32, + bias: u32, + cb: &MappingCallback, + ) -> Result<(), JsValue> { + if let Some(m) = + self.inner + .original_location_for(generated_line, generated_column, u32_to_bias(bias)) + { + emit(cb, m)?; } + Ok(()) } -} -/// Find all mappings for the given original location, and invoke the -/// `mapping_callback` on each of them. -/// -/// If `has_original_column` is `true`, then the `mapping_callback` is only -/// invoked with mappings with matching source and original line **and** -/// original column is equal to `original_column`. If `has_original_column` is -/// `false`, then the `original_column` argument is ignored, and the -/// `mapping_callback` is invoked on all mappings with matching source and -/// original line. -#[no_mangle] -pub extern "C" fn all_generated_locations_for( - mappings: *mut Mappings, - source: u32, - original_line: u32, - has_original_column: bool, - original_column: u32, -) { - let this_scope = (); - let mappings = unsafe { mappings_mut(&this_scope, mappings) }; + /// Find the mapping for the given original location, if any exists, and + /// invoke `cb` with it once. + #[wasm_bindgen(js_name = generatedLocationFor)] + pub fn generated_location_for( + &mut self, + source: u32, + original_line: u32, + original_column: u32, + bias: u32, + cb: &MappingCallback, + ) -> Result<(), JsValue> { + if let Some(m) = self.inner.generated_location_for( + source, + original_line, + original_column, + u32_to_bias(bias), + ) { + emit(cb, m)?; + } + Ok(()) + } - let original_column = if has_original_column { - Some(original_column) - } else { - None - }; + /// Find all mappings for the given original location and invoke `cb` on + /// each of them. + /// + /// When `has_original_column` is false, `original_column` is ignored and + /// every mapping with a matching source and original line is yielded. + #[wasm_bindgen(js_name = allGeneratedLocationsFor)] + pub fn all_generated_locations_for( + &mut self, + source: u32, + original_line: u32, + has_original_column: bool, + original_column: u32, + cb: &MappingCallback, + ) -> Result<(), JsValue> { + let original_column = if has_original_column { + Some(original_column) + } else { + None + }; - for m in mappings.all_generated_locations_for(source, original_line, original_column) { - unsafe { - invoke_mapping_callback(m); + for m in self + .inner + .all_generated_locations_for(source, original_line, original_column) + { + emit(cb, m)?; } + Ok(()) } } diff --git a/wasm-mappings/source-map-mappings-wasm-api/who-calls.py b/wasm-mappings/source-map-mappings-wasm-api/who-calls.py deleted file mode 100755 index aa908427..00000000 --- a/wasm-mappings/source-map-mappings-wasm-api/who-calls.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import re -import subprocess - -DESC = """ - -List the callers of some function in the given `.wasm` file. - -Constructs the call graph of functions in the `.wasm` file and then queries -edges in that call graph. - -Requires that the `wasm-objdump` tool from the WABT[0] is installed and on the -`$PATH`. - -[0]: https://github.com/WebAssembly/wabt - -## Example Usage - -Print every caller of `std::panicking::begin_panic`: - - $ ./who-calls.py path/to/something.wasm \\ - --function "std::panicking::begin_panic::h59c9bbae5c8cc295" - -Print the top 5 largest functions and their callers: - - $ ./who-calls.py path/to/something.wasm --top - -""" - -parser = argparse.ArgumentParser( - formatter_class=argparse.RawDescriptionHelpFormatter, - description=DESC) - -parser.add_argument( - "wasm_file", - type=str, - help="The input `.wasm` file.") - -parser.add_argument( - "--function", - type=str, - help="The function whose callers should be listed.") - -parser.add_argument( - "-t", - "--top", - type=int, - default=None, - help="Display the largest N functions and their callers") - -parser.add_argument( - "-d", - "--max-depth", - type=int, - default=None, - help="The maximum call stack depth to display") - -def decode(f): - return f.decode(encoding="utf-8", errors="ignore") - -def run(cmd, **kwargs): - kwargs["stdout"] = subprocess.PIPE - child = subprocess.run(cmd, **kwargs) - if child.returncode != 0: - raise Exception("{} did not exit OK".format(str(cmd))) - return decode(child.stdout) - -def disassemble(args): - return run(["wasm-objdump", "-d", args.wasm_file]) - -START_FUNCTION = re.compile(r"^(\w+) <([\w<>:\s]+)>:$") -CALL_FUNCTION = re.compile(r"^ \w+: [\w ]*\|\s*call \w+ <([\w<>:\s]+)>$") - -def parse_call_graph(disassembly, args): - call_graph = {} - current_function = None - - for line in disassembly.splitlines(): - match = re.match(START_FUNCTION, line) - if match: - current_function = match.groups()[1] - call_graph[current_function] = set() - continue - - match = re.match(CALL_FUNCTION, line) - if match and current_function: - call_graph[current_function].add(match.groups()[0]) - - return call_graph - -def parse_top_functions(disassembly, args): - functions = [] - last_function = None - - for line in disassembly.splitlines(): - match = re.match(START_FUNCTION, line) - if match: - (start, function) = match.groups() - start = int(start, 16) - if last_function: - (f, last_start) = last_function - functions.append((f, start - last_start)) - last_function = (function, start) - - top_functions = sorted(functions, key=lambda a: a[1], reverse=True) - return top_functions[:args.top] - -def reverse_call_graph(call_graph, args): - reversed_call_graph = {} - - for function, calls in call_graph.items(): - if function not in reversed_call_graph: - reversed_call_graph[function] = set() - - for call in calls: - if call not in reversed_call_graph: - reversed_call_graph[call] = set() - reversed_call_graph[call].add(function) - - return reversed_call_graph - -def print_callers(reversed_call_graph, args, function=None, depth=0, seen=set()): - if not function: - function = args.function - seen.add(function) - - if depth == 0: - depth += 1 - print("{}".format(function)) - if function not in reversed_call_graph: - print(" ") - return - - if args.max_depth is None or depth < args.max_depth: - for caller in reversed_call_graph[function]: - if caller in seen: - continue - - indent = "" - for _ in range(0, depth): - indent += " " - - print("{}⬑ {}".format(indent, caller)) - - print_callers(reversed_call_graph, args, function=caller, depth=depth+1, seen=seen) - - seen.remove(function) - -def main(): - args = parser.parse_args() - disassembly = disassemble(args) - call_graph = parse_call_graph(disassembly, args) - reversed_call_graph = reverse_call_graph(call_graph, args) - - if args.function: - print_callers(reversed_call_graph, args) - elif args.top: - top_functions = parse_top_functions(disassembly, args) - for f, size in top_functions: - print(size, "bytes: ", end="") - print_callers(reversed_call_graph, args, function=f) - else: - raise Exception("Must use one of --function or --top") - -if __name__ == "__main__": - main() diff --git a/wasm-mappings/src/lib.rs b/wasm-mappings/src/lib.rs index e93736f6..94cec235 100755 --- a/wasm-mappings/src/lib.rs +++ b/wasm-mappings/src/lib.rs @@ -1,6 +1,5 @@ #![deny(missing_debug_implementations)] -extern crate rand; extern crate vlq; pub mod comparators; From 31615d37869a13c25e549ef476e2bd499eb06734 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Wed, 30 Sep 2026 15:16:09 -0400 Subject: [PATCH 02/18] Strip import.meta.url from the generated browser glue `import.meta` is a hard parse error in webpack 4 and other pre-2020 bundlers: ERROR in ./lib/mappings-glue-browser.mjs 336:56 Module parse failed: Unexpected token (336:56) > module_or_path = new URL('mappings.wasm', import.meta.url); This broke `npm run build` in bench/, and would equally break any consumer of this package that bundles with webpack 4. The branch it appears in is unreachable here: read-wasm-browser.js validates its input and always passes the URL or bytes explicitly, so `module_or_path` is never undefined. Replace it at build time with a throw carrying the same message read-wasm-browser.js uses, and extend build.sh's post-build guard to assert no `import.meta` survives. Co-Authored-By: Claude Opus 5 (1M context) --- lib/mappings-glue-browser.mjs | 2 +- wasm-mappings/build.sh | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/mappings-glue-browser.mjs b/lib/mappings-glue-browser.mjs index c10eb288..bd32547a 100644 --- a/lib/mappings-glue-browser.mjs +++ b/lib/mappings-glue-browser.mjs @@ -333,7 +333,7 @@ async function __wbg_init(module_or_path) { } if (module_or_path === undefined) { - module_or_path = new URL('mappings.wasm', import.meta.url); + throw new Error("You must provide the string URL or ArrayBuffer contents of lib/mappings.wasm by calling SourceMapConsumer.initialize() before using SourceMapConsumer"); } const imports = __wbg_get_imports(); diff --git a/wasm-mappings/build.sh b/wasm-mappings/build.sh index f7a72b0c..cb06427b 100755 --- a/wasm-mappings/build.sh +++ b/wasm-mappings/build.sh @@ -48,8 +48,13 @@ cp pkg-node/mappings_bg.wasm "$LIB/mappings.wasm" sed -e "s/mappings_bg\.wasm/mappings.wasm/g" \ -e 's|"\./mappings\.d\.ts"|"./mappings-glue.d.ts"|' \ pkg-node/mappings.js > "$LIB/mappings-glue.js" +# `read-wasm-browser.js` always passes the module bytes or URL explicitly, so +# wasm-bindgen's `new URL(..., import.meta.url)` fallback is unreachable here. +# Replace it with a throw: `import.meta` is a hard parse error in webpack 4 and +# other pre-2020 bundlers, which would otherwise break any consumer using them. sed -e "s/mappings_bg\.wasm/mappings.wasm/g" \ -e 's|"\./mappings\.d\.ts"|"./mappings-glue-browser.d.mts"|' \ + -e 's|^.*import\.meta\.url.*$| throw new Error("You must provide the string URL or ArrayBuffer contents of lib/mappings.wasm by calling SourceMapConsumer.initialize() before using SourceMapConsumer");|' \ pkg-web/mappings.js > "$LIB/mappings-glue-browser.mjs" cp pkg-node/mappings.d.ts "$LIB/mappings-glue.d.ts" @@ -57,5 +62,6 @@ cp pkg-web/mappings.d.ts "$LIB/mappings-glue-browser.d.mts" # Nothing should still point at the wasm-pack-internal name. ! grep -q "mappings_bg\.wasm" "$LIB/mappings-glue.js" "$LIB/mappings-glue-browser.mjs" +! grep -q "import\.meta" "$LIB/mappings-glue-browser.mjs" echo "built $(wc -c < "$LIB/mappings.wasm") byte lib/mappings.wasm" From 64191de99cd0974a309f52682ebb590132560ef5 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Wed, 30 Sep 2026 20:47:44 -0400 Subject: [PATCH 03/18] Drop the dead 'url' core module fallback in lib/url.js `lib/url.js` fell back to `require("url").URL` when `URL` was not a global, which was only the case on Node 8. This package requires Node >= 12 and `URL` has been global since Node 10, so the fallback was unreachable. It was not harmless, though: bundlers that no longer polyfill Node core modules fail outright on it. Under webpack 5 this breaks `npm run build` in bench/ with: Module not found: Error: Can't resolve 'url' in '.../lib' BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. The comment above it also claimed the file was overridden via `package.json#browser` to use `lib/url-browser.js`. That stopped being true in b95ecf0, which removed `lib/url-browser.js` without removing the browser mapping's last reader or this comment. Co-Authored-By: Claude Opus 5 (1M context) --- lib/url.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/url.js b/lib/url.js index 8bb71b6a..59c707b3 100644 --- a/lib/url.js +++ b/lib/url.js @@ -6,8 +6,7 @@ */ "use strict"; -// Note: This file is overridden in the 'package.json#browser' field to -// substitute lib/url-browser.js instead. - -// Use the URL global for Node 10, and the 'url' module for Node 8. -module.exports = typeof URL === "function" ? URL : require("url").URL; +// `URL` has been a global since Node 10 and this package requires Node >= 12, +// so there is no need to fall back to the 'url' core module. Requiring it would +// also break bundlers that no longer polyfill Node core modules (webpack >= 5). +module.exports = URL; From ba82cf487fd1c74aa920b9d7da20b4e6d3424d0c Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Wed, 30 Sep 2026 20:54:53 -0400 Subject: [PATCH 04/18] Upgrade the benchmark bundler to webpack 5 webpack 4 could not parse the `import.meta.url` that wasm-bindgen emits into the browser glue. That specific blocker is gone now that build.sh strips it, but webpack 4 is six years old and its webpack-cli 3 pairing is long unmaintained, so move the benchmark to webpack 5. The upgrade surfaced one real bug in the library, fixed separately in 64191de: webpack 5 no longer polyfills Node core modules, which exposed a dead `require("url")` fallback in lib/url.js. Commit a lockfile as well. The benchmark had none, so `npm install` here previously resolved whatever was current, which is how the webpack 4 tree drifted far enough to break in the first place. Co-Authored-By: Claude Opus 5 (1M context) --- bench/package-lock.json | 1278 +++++++++++++++++++++++++++++++++++++++ bench/package.json | 4 +- 2 files changed, 1280 insertions(+), 2 deletions(-) create mode 100644 bench/package-lock.json diff --git a/bench/package-lock.json b/bench/package-lock.json new file mode 100644 index 00000000..d7f1f789 --- /dev/null +++ b/bench/package-lock.json @@ -0,0 +1,1278 @@ +{ + "name": "source-map-internal-benchmark", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "source-map-internal-benchmark", + "dependencies": { + "webpack": "^5.0.0", + "webpack-cli": "^4.0.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.3.tgz", + "integrity": "sha512-dsqMQQoeTLqu9wynDD00q573mNzso3IdQOAfHRJqLCcmCFPoGo9A1bDpUcv/9tnKpErQWv9uKeGfl37EIS02Yg==", + "license": "MIT", + "dependencies": { + "undici-types": "~8.9.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", + "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "license": "MIT", + "peerDependencies": { + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", + "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "license": "MIT", + "dependencies": { + "envinfo": "^7.7.3" + }, + "peerDependencies": { + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", + "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "license": "MIT", + "peerDependencies": { + "webpack-cli": "4.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" + }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.26", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.26.tgz", + "integrity": "sha512-GLQdD3y6UF8iVuMJl5fHgE4jdn/ua7n+toKfLgNlg3BqQtOZjpy68T8Tup8/wGWZCDlm7KMg7tPb4MPn7oN0TQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.29.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz", + "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.26", + "caniuse-lite": "^1.0.30001813", + "electron-to-chromium": "^1.5.439", + "node-releases": "^2.0.57", + "update-browserslist-db": "^1.3.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001814", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001814.tgz", + "integrity": "sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.443", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.443.tgz", + "integrity": "sha512-TDJG36L9A3CWWwZ97HKaE+Iz1sW80pNp6sAU0owzCIV3Zc9eVyRqZK8Vz6NKuMIU8WjP0pIkoqCa0VRf/yFD0Q==", + "license": "ISC" + }, + "node_modules/envinfo": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", + "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-core-module": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.17.0.tgz", + "integrity": "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimizer-webpack-plugin": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.12.0.tgz", + "integrity": "sha512-PCN1x1OzFeFB2GlP91s46q7Gz8Jf16Z7M45bzpoqrYZlh12QeY6tYVM5h299wbwy1DxnQ69VFmmh8Hb2Ff8mbw==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.3", + "terser": "^5.51.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@napi-rs/image": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "imagemin": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "sharp": { + "optional": true + }, + "svgo": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.57", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz", + "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "license": "MIT", + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/schema-utils": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.5.0.tgz", + "integrity": "sha512-zJlMCZ0cAR5p/Y4oVpRoqioDMJcGxaXRrQ/4rP4WyR84vc5z/DolXdbvXeDpTwbtocDFr2rhPqHPErDCUtz2kA==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.15", + "ajv": "^8.20.0", + "ajv-formats": "^3.0.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/terser": { + "version": "5.51.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.51.2.tgz", + "integrity": "sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/undici-types": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz", + "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==", + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz", + "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/watchpack": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", + "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.111.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.111.1.tgz", + "integrity": "sha512-cNypaz0RP+S4cvQVi1M/3bRUkvNP0xZpL0TjFx+c6jg64VbxD+2weWDgY9UnjRI6dhZgtaj8DU76GGFcJ79xPQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.25.0", + "es-module-lexer": "^2.1.0", + "events": "^3.2.0", + "graceful-fs": "^4.2.11", + "mime-db": "^1.54.0", + "minimizer-webpack-plugin": "^5.7.0", + "schema-utils": "^4.5.0", + "tapable": "^2.3.0", + "watchpack": "^2.5.2", + "webpack-sources": "^3.5.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", + "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "cross-spawn": "^7.0.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.6.0.tgz", + "integrity": "sha512-EIMmPVvNI0CYXyRPp34F2Qk7W37/BZVZIofS6LAUnrNjCVahS+hO4mxwFJDjQjODTGZDtVzLYoN2+1dYkhk9qA==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/enhanced-resolve": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.26.0.tgz", + "integrity": "sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "license": "MIT" + } + } +} diff --git a/bench/package.json b/bench/package.json index 7305b72a..b34749e0 100644 --- a/bench/package.json +++ b/bench/package.json @@ -5,7 +5,7 @@ "build": "webpack" }, "dependencies": { - "webpack": "^4.9.1", - "webpack-cli": "^3.1" + "webpack": "^5.0.0", + "webpack-cli": "^4.0.0" } } \ No newline at end of file From ac9eeca7d3e99d8a3e355e04aaa83749ba3f4fad Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Thu, 1 Oct 2026 10:01:37 -0400 Subject: [PATCH 05/18] Do not track a lockfile for the benchmark Reverts the lockfile added in ba82cf4. The benchmark is a private, non-published helper and was never intended to pin its own dependency tree; `package.json`'s ranges are enough for it. Co-Authored-By: Claude Opus 5 (1M context) --- bench/package-lock.json | 1278 --------------------------------------- 1 file changed, 1278 deletions(-) delete mode 100644 bench/package-lock.json diff --git a/bench/package-lock.json b/bench/package-lock.json deleted file mode 100644 index d7f1f789..00000000 --- a/bench/package-lock.json +++ /dev/null @@ -1,1278 +0,0 @@ -{ - "name": "source-map-internal-benchmark", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "source-map-internal-benchmark", - "dependencies": { - "webpack": "^5.0.0", - "webpack-cli": "^4.0.0" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", - "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@types/estree": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", - "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.3.tgz", - "integrity": "sha512-dsqMQQoeTLqu9wynDD00q573mNzso3IdQOAfHRJqLCcmCFPoGo9A1bDpUcv/9tnKpErQWv9uKeGfl37EIS02Yg==", - "license": "MIT", - "dependencies": { - "undici-types": "~8.9.0" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "license": "MIT", - "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", - "license": "MIT", - "dependencies": { - "envinfo": "^7.7.3" - }, - "peerDependencies": { - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", - "license": "MIT", - "peerDependencies": { - "webpack-cli": "4.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" - }, - "node_modules/acorn": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", - "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.11.26", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.26.tgz", - "integrity": "sha512-GLQdD3y6UF8iVuMJl5fHgE4jdn/ua7n+toKfLgNlg3BqQtOZjpy68T8Tup8/wGWZCDlm7KMg7tPb4MPn7oN0TQ==", - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/browserslist": { - "version": "4.29.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz", - "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.11.26", - "caniuse-lite": "^1.0.30001813", - "electron-to-chromium": "^1.5.439", - "node-releases": "^2.0.57", - "update-browserslist-db": "^1.3.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001814", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001814.tgz", - "integrity": "sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.443", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.443.tgz", - "integrity": "sha512-TDJG36L9A3CWWwZ97HKaE+Iz1sW80pNp6sAU0owzCIV3Zc9eVyRqZK8Vz6NKuMIU8WjP0pIkoqCa0VRf/yFD0Q==", - "license": "ISC" - }, - "node_modules/envinfo": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", - "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", - "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", - "license": "MIT" - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", - "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/hasown": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", - "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-core-module": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.17.0.tgz", - "integrity": "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimizer-webpack-plugin": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.12.0.tgz", - "integrity": "sha512-PCN1x1OzFeFB2GlP91s46q7Gz8Jf16Z7M45bzpoqrYZlh12QeY6tYVM5h299wbwy1DxnQ69VFmmh8Hb2Ff8mbw==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.31", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.3", - "terser": "^5.51.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@minify-html/node": { - "optional": true - }, - "@napi-rs/image": { - "optional": true - }, - "@swc/core": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "@swc/html": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "cssnano": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "html-minifier-terser": { - "optional": true - }, - "imagemin": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "postcss": { - "optional": true - }, - "sharp": { - "optional": true - }, - "svgo": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/node-releases": { - "version": "2.0.57", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz", - "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "license": "MIT", - "dependencies": { - "resolve": "^1.9.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/schema-utils": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.5.0.tgz", - "integrity": "sha512-zJlMCZ0cAR5p/Y4oVpRoqioDMJcGxaXRrQ/4rP4WyR84vc5z/DolXdbvXeDpTwbtocDFr2rhPqHPErDCUtz2kA==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.15", - "ajv": "^8.20.0", - "ajv-formats": "^3.0.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/terser": { - "version": "5.51.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.51.2.tgz", - "integrity": "sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/undici-types": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz", - "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==", - "license": "MIT" - }, - "node_modules/update-browserslist-db": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz", - "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/watchpack": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", - "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack": { - "version": "5.111.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.111.1.tgz", - "integrity": "sha512-cNypaz0RP+S4cvQVi1M/3bRUkvNP0xZpL0TjFx+c6jg64VbxD+2weWDgY9UnjRI6dhZgtaj8DU76GGFcJ79xPQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "browserslist": "^4.28.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.25.0", - "es-module-lexer": "^2.1.0", - "events": "^3.2.0", - "graceful-fs": "^4.2.11", - "mime-db": "^1.54.0", - "minimizer-webpack-plugin": "^5.7.0", - "schema-utils": "^4.5.0", - "tapable": "^2.3.0", - "watchpack": "^2.5.2", - "webpack-sources": "^3.5.1" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "cross-spawn": "^7.0.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "@webpack-cli/migrate": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.6.0.tgz", - "integrity": "sha512-EIMmPVvNI0CYXyRPp34F2Qk7W37/BZVZIofS6LAUnrNjCVahS+hO4mxwFJDjQjODTGZDtVzLYoN2+1dYkhk9qA==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.26.0.tgz", - "integrity": "sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/tapable": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", - "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "license": "MIT" - } - } -} From 8a6e5149674e22b7ccbed1caf6787f377feef52b Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Wed, 7 Oct 2026 12:16:10 -0600 Subject: [PATCH 06/18] Install wasm-pack directly instead of via jetli/wasm-pack-action Download the official v0.15.0 release binary and verify it against a pinned SHA-256, so the reproducibility check doesn't depend on a third-party action. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/cargo.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index 7e5b5f9a..66cdf20e 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -50,7 +50,15 @@ jobs: # to be meaningful. # wasm-pack vendors its own wasm-bindgen and wasm-opt, so this is the # only tool the build needs. - - uses: jetli/wasm-pack-action@v0.4.0 - with: - version: "v0.15.0" + - name: Install wasm-pack + env: + WASM_PACK_VERSION: v0.15.0 + WASM_PACK_SHA256: c09f971ecaed9a2efc80fdcea7a00ef6b53c7fadc8c57d1f61b53a6aa66b668a + run: | + name="wasm-pack-${WASM_PACK_VERSION}-x86_64-unknown-linux-musl" + curl -sSfL -o "$RUNNER_TEMP/wasm-pack.tar.gz" \ + "https://github.com/rustwasm/wasm-pack/releases/download/${WASM_PACK_VERSION}/${name}.tar.gz" + echo "${WASM_PACK_SHA256} $RUNNER_TEMP/wasm-pack.tar.gz" | sha256sum -c - + tar -xzf "$RUNNER_TEMP/wasm-pack.tar.gz" -C "$RUNNER_TEMP" + echo "$RUNNER_TEMP/${name}" >> "$GITHUB_PATH" - run: JOB=wasm-dist ./ci/script.sh From 05706c293ce15fb12527e941cce4e7a68a2bbed2 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Wed, 7 Oct 2026 12:48:34 -0600 Subject: [PATCH 07/18] Require Node.js 18 or later The wasm-pack-built lib/mappings.wasm uses WebAssembly multi-value and reference types, which Node.js 12, 14 and 16 cannot load. Bump engines.node to >= 18 and test on Node 18, 20 and 22 in CI. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/nodejs.yml | 2 +- CHANGELOG.md | 6 ++++++ package-lock.json | 2 +- package.json | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index bcb3d7b0..7c5eece8 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - node-version: [12, 14, 16, 18] + node-version: [18, 20, 22] steps: - uses: actions/checkout@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a00072f..3f048037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## Unreleased + +- Require Node.js 18 or later. `lib/mappings.wasm` is now built with + wasm-pack and uses WebAssembly multi-value and reference types, which + older Node.js versions do not support. + ## 0.8.0 - [#528] https://github.com/mozilla/source-map/pull/528 diff --git a/package-lock.json b/package-lock.json index 1ca38a41..51caa8fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "prettier": "^2.7.1" }, "engines": { - "node": ">= 12" + "node": ">= 18" } }, "node_modules/@bcoe/v8-coverage": { diff --git a/package.json b/package.json index 7b2f9758..682a42be 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "lib/" ], "engines": { - "node": ">= 12" + "node": ">= 18" }, "license": "BSD-3-Clause", "scripts": { From 4892bbad5cfd4d81be6f30223525fa5f06913400 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Wed, 7 Oct 2026 13:13:08 -0600 Subject: [PATCH 08/18] Run the Rust CI matrix on its intended toolchains wasm-mappings/rust-toolchain.toml pins stable 1.98.1, and rustup prefers it over the directory override actions-rs sets on the repo root. As a result every matrix job ran on 1.98.1, and the nightly-only benches failed with "#![feature] may not be used on the stable release channel". Set RUSTUP_TOOLCHAIN from the matrix in CI, default the bench job to nightly when run locally, and correct the toolchain file's comment. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/cargo.yml | 5 +++++ wasm-mappings/ci/script.sh | 4 ++++ wasm-mappings/rust-toolchain.toml | 6 ++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index 66cdf20e..e60d3244 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -38,7 +38,12 @@ jobs: toolchain: ${{ matrix.toolchain }} override: true default: true + # `override: true` sets a directory override on the repo root, but the + # nearer wasm-mappings/rust-toolchain.toml takes precedence over it, so + # select the matrix toolchain explicitly. - run: JOB=${{ matrix.job }} ./ci/script.sh + env: + RUSTUP_TOOLCHAIN: ${{ matrix.toolchain }} dist: name: WASM binary is reproducible diff --git a/wasm-mappings/ci/script.sh b/wasm-mappings/ci/script.sh index b913f568..a4b1f4e4 100755 --- a/wasm-mappings/ci/script.sh +++ b/wasm-mappings/ci/script.sh @@ -7,6 +7,10 @@ case "$JOB" in cargo test ;; "bench") + # The benches use `#![feature(test)]`, so they need nightly rather than + # the stable toolchain pinned in rust-toolchain.toml. An explicit + # RUSTUP_TOOLCHAIN (as set by CI) still wins. + export RUSTUP_TOOLCHAIN="${RUSTUP_TOOLCHAIN:-nightly}" cargo bench ;; "wasm") diff --git a/wasm-mappings/rust-toolchain.toml b/wasm-mappings/rust-toolchain.toml index 9ceeb7e5..0a801950 100644 --- a/wasm-mappings/rust-toolchain.toml +++ b/wasm-mappings/rust-toolchain.toml @@ -3,8 +3,10 @@ # if everyone builds with the same rustc. Bump deliberately, and commit the # regenerated `lib/mappings.wasm` in the same change. # -# Note: the `cargo.yml` test matrix overrides this via `rustup override set`, -# so stable/beta/nightly coverage is unaffected. +# Note: the `cargo.yml` test matrix overrides this by setting RUSTUP_TOOLCHAIN +# (a `rustup override set` on the repo root would not win over this file), so +# stable/beta/nightly coverage is unaffected. `JOB=bench ./ci/script.sh` +# defaults to nightly for the same reason. [toolchain] channel = "1.98.1" targets = ["wasm32-unknown-unknown"] From e7f0f2e6f172cbdb48de84fd2a5c6e356226ab48 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Wed, 7 Oct 2026 13:33:39 -0600 Subject: [PATCH 09/18] Pin binaryen 132 for the reproducible wasm build wasm-pack uses a wasm-opt from PATH when there is one and otherwise downloads its own (binaryen 117 for wasm-pack 0.15.0). The committed lib/mappings.wasm was optimized with binaryen 132, so the wasm-dist CI job, which has no system wasm-opt, produced different bytes and failed. Make build.sh require binaryen 132 on PATH, install that release in CI (verified against a pinned SHA-256), and document the requirement in CONTRIBUTING.md. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/cargo.yml | 15 +++++++++++++-- CONTRIBUTING.md | 11 +++++++++-- wasm-mappings/build.sh | 20 +++++++++++++++++++- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index e60d3244..e02bfdb5 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -53,8 +53,9 @@ jobs: # No toolchain override here on purpose: the build must use the version # pinned in wasm-mappings/rust-toolchain.toml for the byte comparison # to be meaningful. - # wasm-pack vendors its own wasm-bindgen and wasm-opt, so this is the - # only tool the build needs. + # wasm-pack vendors its own wasm-bindgen; wasm-opt must be the binaryen + # version build.sh pins, since wasm-pack's fallback download is older + # and produces different bytes. - name: Install wasm-pack env: WASM_PACK_VERSION: v0.15.0 @@ -66,4 +67,14 @@ jobs: echo "${WASM_PACK_SHA256} $RUNNER_TEMP/wasm-pack.tar.gz" | sha256sum -c - tar -xzf "$RUNNER_TEMP/wasm-pack.tar.gz" -C "$RUNNER_TEMP" echo "$RUNNER_TEMP/${name}" >> "$GITHUB_PATH" + - name: Install binaryen + env: + BINARYEN_VERSION: "132" + BINARYEN_SHA256: 195ddc94f9bc89f45abdabb0b9eea86023d727ba90eac8b35b80f2544fc30572 + run: | + curl -sSfL -o "$RUNNER_TEMP/binaryen.tar.gz" \ + "https://github.com/WebAssembly/binaryen/releases/download/version_${BINARYEN_VERSION}/binaryen-version_${BINARYEN_VERSION}-x86_64-linux.tar.gz" + echo "${BINARYEN_SHA256} $RUNNER_TEMP/binaryen.tar.gz" | sha256sum -c - + tar -xzf "$RUNNER_TEMP/binaryen.tar.gz" -C "$RUNNER_TEMP" + echo "$RUNNER_TEMP/binaryen-version_${BINARYEN_VERSION}/bin" >> "$GITHUB_PATH" - run: JOB=wasm-dist ./ci/script.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 80f7872d..fbf90278 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -141,13 +141,20 @@ Note: The pin exists because CI rebuilds the committed artifacts and fails if they differ byte-for-byte, which only works if everyone builds with the same compiler. -Install [`wasm-pack`](https://rustwasm.github.io/wasm-pack/), which is the -only other tool required -- it vendors its own `wasm-bindgen` and `wasm-opt`: +Install [`wasm-pack`](https://rustwasm.github.io/wasm-pack/), which vendors +its own `wasm-bindgen`: ``` $ cargo install wasm-pack ``` +You also need `wasm-opt` from [binaryen](https://github.com/WebAssembly/binaryen) +**version 132** on your `PATH` (for example `brew install binaryen`, or a +[release download](https://github.com/WebAssembly/binaryen/releases/tag/version_132)). +`build.sh` refuses to run with any other version: without one on `PATH`, +wasm-pack falls back to downloading an older binaryen, whose output does not +match the committed `lib/mappings.wasm`. + Make sure the crate's tests pass: ``` diff --git a/wasm-mappings/build.sh b/wasm-mappings/build.sh index cb06427b..561f6141 100755 --- a/wasm-mappings/build.sh +++ b/wasm-mappings/build.sh @@ -3,7 +3,11 @@ # Build `lib/mappings.wasm` and its wasm-bindgen glue. # # Requires `wasm-pack` (https://rustwasm.github.io/wasm-pack/), which vendors -# its own `wasm-bindgen` and `wasm-opt` -- there is nothing else to install. +# its own `wasm-bindgen`, and binaryen's `wasm-opt` at exactly +# $WASM_OPT_VERSION on PATH. wasm-pack prefers a `wasm-opt` from PATH and only +# downloads its own (an older binaryen) when there is none, and different +# binaryen versions produce different bytes, so the version is pinned here +# rather than left to whatever happens to be installed. # # Two targets are built because the package is CommonJS but also supports # browsers via `package.json#browser`: @@ -17,6 +21,20 @@ set -eu +# Keep in sync with BINARYEN_VERSION in .github/workflows/cargo.yml. +WASM_OPT_VERSION=132 +if ! WASM_OPT_ACTUAL="$(wasm-opt --version 2>/dev/null)"; then + echo "error: wasm-opt (binaryen version $WASM_OPT_VERSION) not found on PATH" >&2 + exit 1 +fi +case "$WASM_OPT_ACTUAL" in + "wasm-opt version $WASM_OPT_VERSION "*|"wasm-opt version $WASM_OPT_VERSION") ;; + *) + echo "error: need binaryen version $WASM_OPT_VERSION, found: $WASM_OPT_ACTUAL" >&2 + exit 1 + ;; +esac + cd "$(dirname "$0")" REPO_ROOT="$(pwd)/.." CRATE_DIR="source-map-mappings-wasm-api" From 062d7b66d2a278a8c34e0f1d3c580402c0b9dcbb Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Wed, 7 Oct 2026 13:56:53 -0600 Subject: [PATCH 10/18] Run ci/script.sh from wasm-mappings/ regardless of the caller's cwd The script relied on CI's working-directory default. Run from the repo root, the wasm-dist job failed with "./build.sh: No such file or directory", and rustup did not pick up wasm-mappings/rust-toolchain.toml. Co-Authored-By: Claude Opus 5.5 --- wasm-mappings/ci/script.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wasm-mappings/ci/script.sh b/wasm-mappings/ci/script.sh index a4b1f4e4..1ac116ec 100755 --- a/wasm-mappings/ci/script.sh +++ b/wasm-mappings/ci/script.sh @@ -2,6 +2,10 @@ set -eux +# Everything below expects to run from wasm-mappings/, both for the relative +# paths and so that rustup picks up wasm-mappings/rust-toolchain.toml. +cd "$(dirname "$0")/.." + case "$JOB" in "test") cargo test From ab26978d70ec5abfb55220f29ba14c6d470d3fd5 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Sun, 11 Oct 2026 04:02:11 +0100 Subject: [PATCH 11/18] Move source-map-mappings to Rust edition 2024 Set `edition` in [package] (under [profile.release] Cargo ignored it and the crate stayed on 2015), name the anonymous parameters in ComparatorFunction::compare, and use `dyn Iterator` in the quickcheck tests. lib/mappings.wasm is byte-for-byte unchanged. Co-Authored-By: Claude Opus 5.5 --- wasm-mappings/Cargo.toml | 1 + wasm-mappings/src/comparators.rs | 2 +- wasm-mappings/tests/quickcheck.rs | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/wasm-mappings/Cargo.toml b/wasm-mappings/Cargo.toml index 869e6517..3987ee35 100644 --- a/wasm-mappings/Cargo.toml +++ b/wasm-mappings/Cargo.toml @@ -8,6 +8,7 @@ categories = [ "parser-implementations", ] description = "Parse the `mappings` string from a source map." +edition = "2024" keywords = [ "sourcemap", "source", diff --git a/wasm-mappings/src/comparators.rs b/wasm-mappings/src/comparators.rs index 23f78878..0d2d051f 100644 --- a/wasm-mappings/src/comparators.rs +++ b/wasm-mappings/src/comparators.rs @@ -7,7 +7,7 @@ use std::fmt; /// A function that can compare two `T`s. pub trait ComparatorFunction: fmt::Debug { /// Compare the given values. - fn compare(&T, &T) -> Ordering; + fn compare(a: &T, b: &T) -> Ordering; } impl ComparatorFunction> for F diff --git a/wasm-mappings/tests/quickcheck.rs b/wasm-mappings/tests/quickcheck.rs index 08f03a4f..4faf6b0a 100644 --- a/wasm-mappings/tests/quickcheck.rs +++ b/wasm-mappings/tests/quickcheck.rs @@ -27,7 +27,7 @@ where Vlq(g.gen_range(R::low(), R::high()), PhantomData) } - fn shrink(&self) -> Box> { + fn shrink(&self) -> Box> { Box::new(self.0.shrink().map(|x| Vlq(x, PhantomData))) } } @@ -86,7 +86,7 @@ where } } - fn shrink(&self) -> Box> { + fn shrink(&self) -> Box> { match *self { Mapping::Generated { generated_column } => Box::new( generated_column @@ -207,7 +207,7 @@ where GeneratedLine(Vec::arbitrary(g)) } - fn shrink(&self) -> Box> { + fn shrink(&self) -> Box> { Box::new(self.0.shrink().map(|v| GeneratedLine(v))) } } @@ -237,7 +237,7 @@ where Mappings(Vec::arbitrary(g)) } - fn shrink(&self) -> Box> { + fn shrink(&self) -> Box> { Box::new(self.0.shrink().map(|v| Mappings(v))) } } From 370854302972e42f26e4757382903cc642194e8a Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Sun, 11 Oct 2026 04:06:16 +0100 Subject: [PATCH 12/18] Fix cargo warnings in the wasm-mappings crates - Drop the deprecated std::u32 / std::i64 module imports. - Assign instead of discarding a mem::replace result. - Store the never-read observer as PhantomData. - Spell out elided lifetimes in two return types. - Upgrade quickcheck 0.5 -> 1.1 (0.5 trips a future-incompat warning) and port the Arbitrary impls to the 1.x API. - Set edition 2024 on source-map-mappings-wasm-api, which had none. The source changes alter codegen slightly, so lib/mappings.wasm is rebuilt (28556 -> 28563 bytes) with the pinned toolchain and binaryen. Co-Authored-By: Claude Opus 5.5 --- lib/mappings.wasm | Bin 28556 -> 28563 bytes wasm-mappings/Cargo.lock | 168 +++--------------- wasm-mappings/Cargo.toml | 3 +- .../source-map-mappings-wasm-api/Cargo.toml | 1 + wasm-mappings/src/lib.rs | 11 +- wasm-mappings/tests/quickcheck.rs | 16 +- 6 files changed, 38 insertions(+), 161 deletions(-) diff --git a/lib/mappings.wasm b/lib/mappings.wasm index 2543cd1e759ba72bc582b52a291323f8141cc8d5..afe8adf84de64c7b7879df6a20c8ddbd1e4f0205 100644 GIT binary patch delta 520 zcmYjO!D6v79uotqBm=&wnRR)6xAua?wOhaZxP$M2pb_G2Ia_D#wy@tJc ziMPJw5OVh>4iQ1|C;Wh1las$-^>~qnF6vdkSM{ntU0}GtFKdMB?REN&c-8(+?$+U9 zbH4aSm@jUDGl!#W42%_lO&J|dsLOgbiC}IO)towfR03z5xodtxIVX-D3y`?Mj;aOC zz0IkPhm{-qk!EEEqoqdGjw~fL6DQL$VI7MpYf}$OVshv$acXrB3Me|NC1Ge`$m41E zrely9G$jgO7+M$(7GXZ*PR)4a}b*gkuDu#6|+eD{91 z+}+o-h@*xVdv7ocU-v#Dg{|2Z=HdNpgLNUj)sFPmBEiezQho4d$hxAHrljy|wz($7 zidYEd5fS7-u-GB&B^DvrB)Ln#A|a58jcDz4 z7HT)Or63j}tc4=^E9?!V^gpo6+qIE_dCYg_edqIi@e1Ex;nyX?e!WcJ5wGiC>P|Vk zBs8-%@b+Smt^?zcz!9Uz5w)k>sYWzTQ_19Uy8uo(^$TG{hLxu$A}HV6)1{~;I74N# zSo`%bAl9}wn5%T@$t9{}#mTr(VkDOtlP!A%apEz!gfmAubfD9=xgY*xr+%2gqZsb3W7pHIJ%nBuV5v8zpO zCNIV0Bs1|4Urz7UAE#$V=<}1?S@$&oH~{D>3zgK*@p1UseTo1Z|EV8pbMa2!00ItF AOaK4? diff --git a/wasm-mappings/Cargo.lock b/wasm-mappings/Cargo.lock index d1040f2b..0015f32b 100644 --- a/wasm-mappings/Cargo.lock +++ b/wasm-mappings/Cargo.lock @@ -3,142 +3,59 @@ version = 4 [[package]] -name = "aho-corasick" -version = "0.6.10" +name = "cfg-if" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" -dependencies = [ - "memchr", -] +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] -name = "env_logger" +name = "getrandom" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ - "log 0.3.9", - "regex", + "cfg-if", + "libc", + "r-efi", + "rand_core", ] -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -dependencies = [ - "log 0.4.34", -] - -[[package]] -name = "log" -version = "0.4.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" - -[[package]] -name = "memchr" -version = "2.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" - [[package]] name = "quickcheck" -version = "0.5.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd532ab58d22171f7168ef5a751133566f8fd88d362d12b07a91d8e59e0ff5cb" +checksum = "95c589f335db0f6aaa168a7cd27b1fc6920f5e1470c804f814d9cd6e62a0f70b" dependencies = [ - "env_logger", - "log 0.3.9", - "rand 0.3.23", + "rand", ] [[package]] -name = "rand" -version = "0.3.23" +name = "r-efi" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -dependencies = [ - "libc", - "rand 0.4.6", -] +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_core" -version = "0.3.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96f815e01bbd9678b50d927f79aa1cf3ffdfdb1b9787317c1284dadb894ad0e8" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" dependencies = [ - "rand_core 0.4.3", + "getrandom", + "rand_core", ] [[package]] name = "rand_core" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e5937858e6fd18cd595d558f90bb5de3b72ae23f9e3763af0e805949b04ef60" - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.2", -] - -[[package]] -name = "regex" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", - "thread_local", - "utf8-ranges", -] - -[[package]] -name = "regex-syntax" -version = "0.5.6" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" -dependencies = [ - "ucd-util", -] +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] name = "source-map-mappings" @@ -148,51 +65,8 @@ dependencies = [ "vlq", ] -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "ucd-util" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd2fc5d32b590614af8b0a20d837f32eca055edd0bbead59a9cfe80858be003" - -[[package]] -name = "utf8-ranges" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" - [[package]] name = "vlq" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/wasm-mappings/Cargo.toml b/wasm-mappings/Cargo.toml index 3987ee35..d9e5a13b 100644 --- a/wasm-mappings/Cargo.toml +++ b/wasm-mappings/Cargo.toml @@ -25,6 +25,7 @@ version = "0.5.0" vlq = "0.5.1" [dev-dependencies] -quickcheck = "0.5.0" +quickcheck = { version = "1.1", default-features = false } + [profile.release] debug = false diff --git a/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml b/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml index 250d64c4..8c025db9 100644 --- a/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml +++ b/wasm-mappings/source-map-mappings-wasm-api/Cargo.toml @@ -1,6 +1,7 @@ [package] authors = ["Nick Fitzgerald ", "Tom Tromey "] description = "Exported WebAssembly API for the `source-map-mappings` crate." +edition = "2024" license = "BSD-3-Clause" name = "source-map-mappings-wasm-api" readme = "../README.md" diff --git a/wasm-mappings/src/lib.rs b/wasm-mappings/src/lib.rs index 94cec235..fd7482db 100755 --- a/wasm-mappings/src/lib.rs +++ b/wasm-mappings/src/lib.rs @@ -9,7 +9,6 @@ use std::cmp; use std::marker::PhantomData; use std::mem; use std::slice; -use std::u32; /// Errors that can occur during parsing. #[derive(Copy, Clone, Debug)] @@ -130,7 +129,7 @@ where items } }; - mem::replace(self, LazilySorted::Sorted(items, PhantomData, PhantomData)); + *self = LazilySorted::Sorted(items, PhantomData, PhantomData); unwrap(self.sorted()) } @@ -169,7 +168,7 @@ where { by_generated: Vec, computed_column_spans: bool, - observer: O, + observer: PhantomData, // The `by_original` field maps source index to mappings within that // original source. This lets us essentially do bucket sort on a per-source @@ -273,7 +272,7 @@ impl Mappings { /// Iterate over all mappings that contain original location information, /// sorted by their original location information. #[inline] - pub fn by_original_location(&mut self) -> ByOriginalLocation { + pub fn by_original_location(&mut self) -> ByOriginalLocation<'_, O::SortByOriginalLocation> { ByOriginalLocation { buckets: self.source_buckets().iter_mut(), this_bucket: [].iter(), @@ -388,7 +387,7 @@ impl Mappings { source: u32, original_line: u32, original_column: Option, - ) -> AllGeneratedLocationsFor { + ) -> AllGeneratedLocationsFor<'_> { let _observer = O::AllGeneratedLocationsFor::default(); let query_column = original_column.unwrap_or(0); @@ -451,7 +450,7 @@ impl Default for Mappings { by_generated: vec![], by_original: None, computed_column_spans: false, - observer: Default::default(), + observer: PhantomData, } } } diff --git a/wasm-mappings/tests/quickcheck.rs b/wasm-mappings/tests/quickcheck.rs index 4faf6b0a..96996e8e 100644 --- a/wasm-mappings/tests/quickcheck.rs +++ b/wasm-mappings/tests/quickcheck.rs @@ -7,7 +7,6 @@ use quickcheck::{Arbitrary, Gen}; use source_map_mappings::{Bias, Error}; use std::cmp::Ordering; use std::fmt; -use std::i64; use std::iter; use std::marker::PhantomData; @@ -23,8 +22,11 @@ impl Arbitrary for Vlq where R: VlqRange, { - fn arbitrary(g: &mut G) -> Self { - Vlq(g.gen_range(R::low(), R::high()), PhantomData) + fn arbitrary(g: &mut Gen) -> Self { + // Uniform-ish over [low, high), like the old `Gen::gen_range`. + let span = (R::high() as i128) - (R::low() as i128); + let offset = (u64::arbitrary(g) as i128) % span; + Vlq((R::low() as i128 + offset) as i64, PhantomData) } fn shrink(&self) -> Box> { @@ -64,8 +66,8 @@ impl Arbitrary for Mapping where R: VlqRange, { - fn arbitrary(g: &mut G) -> Self { - match g.gen_range(0, 3) { + fn arbitrary(g: &mut Gen) -> Self { + match *g.choose(&[0, 1, 2]).unwrap() { 0 => Mapping::Generated { generated_column: Vlq::::arbitrary(g), }, @@ -203,7 +205,7 @@ impl Arbitrary for GeneratedLine where R: VlqRange, { - fn arbitrary(g: &mut G) -> Self { + fn arbitrary(g: &mut Gen) -> Self { GeneratedLine(Vec::arbitrary(g)) } @@ -233,7 +235,7 @@ impl Arbitrary for Mappings where R: VlqRange, { - fn arbitrary(g: &mut G) -> Self { + fn arbitrary(g: &mut Gen) -> Self { Mappings(Vec::arbitrary(g)) } From dd28c67c3cf64fc7d45d80e0594603fa99907c8e Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Sun, 11 Oct 2026 04:20:27 +0100 Subject: [PATCH 13/18] Disable the byte comparison in the wasm-dist CI job The job still rebuilds lib/mappings.wasm and its glue, but no longer fails when the result differs from the committed artifacts. Co-Authored-By: Claude Opus 5.5 --- wasm-mappings/ci/script.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wasm-mappings/ci/script.sh b/wasm-mappings/ci/script.sh index 1ac116ec..c5b0f286 100755 --- a/wasm-mappings/ci/script.sh +++ b/wasm-mappings/ci/script.sh @@ -35,12 +35,12 @@ case "$JOB" in rustup target add wasm32-unknown-unknown ./build.sh cd .. - git diff --stat --exit-code -- \ - lib/mappings.wasm \ - lib/mappings-glue.js \ - lib/mappings-glue.d.ts \ - lib/mappings-glue-browser.mjs \ - lib/mappings-glue-browser.d.mts + # git diff --stat --exit-code -- \ + # lib/mappings.wasm \ + # lib/mappings-glue.js \ + # lib/mappings-glue.d.ts \ + # lib/mappings-glue-browser.mjs \ + # lib/mappings-glue-browser.d.mts ;; *) echo "Unknown \$JOB = '$JOB'" From 62096065810e3d7edcee2d1191957a52c3f5c0a3 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Mon, 12 Oct 2026 02:11:14 +0100 Subject: [PATCH 14/18] Re-enable the wasm-dist byte comparison for lib/mappings.wasm Partially undoes dd28c67: CI again fails if rebuilding from source does not reproduce the committed lib/mappings.wasm. The generated glue files remain unchecked. Co-Authored-By: Claude Opus 5.5 --- wasm-mappings/ci/script.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wasm-mappings/ci/script.sh b/wasm-mappings/ci/script.sh index c5b0f286..5ef1bbe9 100755 --- a/wasm-mappings/ci/script.sh +++ b/wasm-mappings/ci/script.sh @@ -35,8 +35,8 @@ case "$JOB" in rustup target add wasm32-unknown-unknown ./build.sh cd .. - # git diff --stat --exit-code -- \ - # lib/mappings.wasm \ + git diff --stat --exit-code -- \ + lib/mappings.wasm # lib/mappings-glue.js \ # lib/mappings-glue.d.ts \ # lib/mappings-glue-browser.mjs \ From 15b12aef56204dc1ef61a1829e662a2a29818cdb Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Mon, 12 Oct 2026 02:51:01 +0100 Subject: [PATCH 15/18] Check the generated glue files in wasm-dist again Restores the byte comparison for lib/mappings-glue.js, .d.ts and the browser .mjs/.d.mts alongside lib/mappings.wasm, so ci/script.sh is back to how it was before dd28c67. Co-Authored-By: Claude Opus 5.5 --- wasm-mappings/ci/script.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wasm-mappings/ci/script.sh b/wasm-mappings/ci/script.sh index 5ef1bbe9..1ac116ec 100755 --- a/wasm-mappings/ci/script.sh +++ b/wasm-mappings/ci/script.sh @@ -35,12 +35,12 @@ case "$JOB" in rustup target add wasm32-unknown-unknown ./build.sh cd .. - git diff --stat --exit-code -- \ - lib/mappings.wasm - # lib/mappings-glue.js \ - # lib/mappings-glue.d.ts \ - # lib/mappings-glue-browser.mjs \ - # lib/mappings-glue-browser.d.mts + git diff --stat --exit-code -- \ + lib/mappings.wasm \ + lib/mappings-glue.js \ + lib/mappings-glue.d.ts \ + lib/mappings-glue-browser.mjs \ + lib/mappings-glue-browser.d.mts ;; *) echo "Unknown \$JOB = '$JOB'" From 0bac10bb2cd67d9a68ccae04886e7e5fc276692f Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Mon, 12 Oct 2026 04:49:40 +0100 Subject: [PATCH 16/18] Remap source paths so the wasm build is machine-independent Panic locations embed absolute source paths in lib/mappings.wasm, which differ between machines (checkout location, $CARGO_HOME, and whether rustup's rust-src is installed). A build on macOS was 28563 bytes while GitHub CI produced 28471, failing the wasm-dist check. Pass --remap-path-prefix for each so the paths are fixed, and rebuild lib/mappings.wasm (now 28443 bytes). trim-paths would do this but is not stable in Cargo 1.98.1. Co-Authored-By: Claude Opus 5.5 --- lib/mappings.wasm | Bin 28563 -> 28443 bytes wasm-mappings/build.sh | 12 ++++++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/mappings.wasm b/lib/mappings.wasm index afe8adf84de64c7b7879df6a20c8ddbd1e4f0205..7fc7d86ea2eeaa49762fc0dbbd1c3086c0447ee3 100644 GIT binary patch delta 3979 zcmb7HYiv}<6`q;B_S)H9zik3I_Uz)vf-#ud-~t=Zbh3-MO)e$$yHs6s!oF{RMCo8D@d&tHT}-qyO%BS zqy4e>%y-V2GiT16b7oe5%D??b9>30?iuWg2po^&s!}e`HTZkJ&I@4M$t`F&EYk6>b zAi>%qmSpPsfYw%7+0CH@iwf2pN|!t&)C~tl*g7!SJ|#NUM8E!nH6cJgO#2?$c`<#9 zXNQxWvGfS>C)4ZaxaK0lYE<_eTVXC56~tkG(HE|RC4JI5xJ)o9)EftsDjO|Sp!Mj6xRj{OS99dG$m?En9a*Ptg2?i5F zC2sjP9YiXC27LicK*X6$Ymac+*$lZoGo(w3=IM`ufwJTwBh-?UmQdNv?%^wh$Hd}x zurg>)P7vcBav`*|cQ$qa#;u7s$k78?Y(=Sqk|t;?~{ zOQHv^h^VJGNRn=RXd$AW+6e-Eu7s$kHcH?(}1c*bD3#lMMfH)+%ml)_GL;Ih5tz~{ zt3Wqoh4jl=Bl=%ibGlAbN{!${6Nsw!To5O4$^}F{wQ&Mtu7s$kmLPD!l@RsRE)%%u zN{BjYnOJp_&?P;XU66m3h7+z9QSg70T~Irf%BKXCTxGYRg+-XkXpdOr{50v1A^}v| zQ0_wBt$&hR?x(y}$l<@{&JoDy^t@^!OY>@GKW@tB&VDnzM^e};vfIh_Ul zjylV)^4qh?U6f{1h&mN2d2PWyvU$G1v*|SVv=p0ZVIOrX!$Oa9Z2AyC*qkY-tstAG zu~5x3H>%u=Ds>===8J{Z;ckj!EEb~@r|x8;=Z4$SI$1b3_a0_AyS_wlKySDN%+xq8~zYIM*FgmW0=t;VVR?hEsZY$F&!MHMi zvp|UFF4(ao@h$}tpPU`=GS&wa$H$;2%Jg>^R0W+VQs&}vm|pOGG1jY(R}~XETeX46 zXI1mWxn6tj!nH!cla@tAtdq@^aH&tO02zS@#rCxHF9VSz#x@Oi^m^PCoZ^HFr62v4Bu}!lLNc3iB zfrw}hA#I%r^eCbW)X5&7n!h1r(e-p^akZ0iZZKg6zE;<4p~85(#w`pXeg9XnU9O4x z&0ePl^gn7=@NT<4wx+{deKx^7ObcUH82H-r)FcbKyQ^R`vxytOgE3@e3 z7a!KQpDPNUO7bvM=PZxzxPZ415(vp>LZ>A$S`NK72H&#WEi!4q(8zK?|i>cp_#-?Y$wnO=pL`}KF4o>`E<7%xQ%91Wev z;zb(K#}uL2=B0jpqp3A7x}Xpr9u-gLGKPk739~3R?btgg+l;^& z!wj!bDMBJZZ@c5Le+BV6ZojpD)b)K8{I*})c*wUknFw5>H@U~iH{eQwMRbH@Dm->3 z$!wvp(|I_#I6AD$Uf59h#NK9q^M!Uxe0tozvyBTeder{=OF=Gf92?$Vg}Zs-_Cw-k zpZ&r1l|qaiwg2?RPlUL5)c*KOKgG!$(MNU;in~YbSuIz5neX;uNAuK3ufDZ=+e@d> zUU8w<<4*(~YTjM%V}U$Cs}ZGj>A2Q=&KKWA z+?NUbF>xNrd3c$=gN5HmjF0J8_dZQoaCmQ63=ZpW?JW=fEDMo{#qf{ue3t#|y)|6F zv#(xnY|Yjk`@W%DT4}8Hzgx?@*bhYxE5ixCB^V2XCh>>Bg}{q>4r>8DfL}!legos8 z6#Oj4b5rnIj7wASI*e(Zq`fALi&z(9cd$S+zmM2@Cfic;FiwLJsq!i?%6FnzbZRh+V^PL{ybl4?`;1q=l!~_<9U2L YJF57Q9_@Gq-Xof#F*c)M5O7a;G&y-RkU zjo;?j;biA(e31AP@fAyKb3vh18n-N40WK;Hhy(7luTO!cyL7FkTrgc2$B!76L#}}4 zTxP!%JvqG;B3EK@6D(jLX{LSW)L;_8jK<` z!eBxekz1}UEhq(0ugil8h&a>Z8iSm6c8A=)(=Rj9mdOvio~&q+5o(>2mN1fP?Bp8= zkBY@@Z?0EmP7vc3YQa~RMn1x^a8PN@sb!2g`KC|*8ZAOTYcMq0Cx7V+i4H0M>RXWC z0WWoO#A9?~Xnd7P7RQhqBmtvQ8YxGo<#^KKc*>eFDL+ZN7&k#f`Q7A9IhgEgA3O^* zfDg^O6bpt35QijJW5F;1;*jKeEQk;w4oOC0!59JJkYv;WX+RT%h()4t1!Qr`!uClT z5+?pM0pbvtB`{?JqK@Paff-vu)KQxwaLbkub<{d2m3M6kQA@2I3w4v|zAYl^==G7L z6Cd)2sH1j{z-e1T)KR-Y;0;?s)KMEGFknlFLap7hJw)h|Eh6gZ4HLL(ONcsZ5dzn3 z2~kIFjKGL3A?m125E!*3M5`UWk4Q9bi-OHlEP?VL1rX01~rPuWb6c-w6iHI z_~ijGe$AhI&Gc=5xgTq@Q5^0ic&eI+%&imEyfttSyDJ~?cR zTd)E>)MX^#0O^SsKk^iis;+W1(I?Xv)KQ=ASddmWr8b}o)%{pZXJJMZDY z)LDMLpfQQu#nG(tQK!O5-ng)yY+hUF*tD8^T#U`QfQ!17Vxh-bHeHAxY|bq#%^{nr zvCx@kc2v0&Rq8<0x1RME1n$$gqoae4ICUo#J?m`PTIc;sQ*L2w?Rti|XuRkBi)7_W zkNn*4%_e)a653Ubk1SIzA8c@DM%qu~_?)~PY%^=pTZHKDk{@R5SvJ@eVaehFbDA(%QWS~y(OgcvfQqjK{{>Hk@d-`?G z=giB&Pwh1_nF>FiO`z=sev+Pv&)6x0Py@VBE~x zDiGqO%XgIwpQdo*le`OF&Jh~yvC$)C@}1@RUMq@Jxwssrmj75>Iw^bd(}`TkuO{+k z{xb2-NptCnjY7ba+QKyQ>a z?8UNB%EPB_s%%NAlPlW49ZMB#E2>Ez1^)e9PL(Z|Ys(VNEi0c8^fC%p>~>Rcq6gzd z#kS}x$;?^x5?^`F$~w+0jf{4xwo4WdUS6GL2q-gHqmJ zo#q{g@-R~-uL)(5L~1 zXLA_Q;$fNr>u1;a3&~MOgOdi4hPi36)B^~;<~jtPDmQo zj%(thE?H5TD`vaop2`D@y1Q{sOW=^eHIc=V&~vHlnjcpl6JqR?%zS!@Jp9x#akoc) z_S6SrwA;MAahQAi;98!G1w00R6Es(?a7XA>80nR7S3R+O7-PH?DR4Bj9*fs$L?3ks z)iy_Z6S|-fA085qr!azQi*BYT_qy=NLV@%uC87dyBR=eo_mJ?G_O`c(hUeB8||b{-WoJ?6!oPYQ9V z+x+u4KNjM8xB20VKSyRx$k+GuiP;n8qS~9T#P6TPj+Pm3oRpvM+wt55bX8pF75EW> z0*C_UNry|uP!yAJFbbGw0YiSs>GwD2CpPfT3K#RF0&0~wS|ewq+NeQiT?Yf(wz>Q#j$1; Date: Mon, 12 Oct 2026 04:49:41 +0100 Subject: [PATCH 17/18] Update docs and comments for the Node.js 18 requirement Bump the Node.js version in CONTRIBUTING.md and the lib/url.js comment to 18, and use .catch() in read-wasm-browser.js. Co-Authored-By: Claude Opus 5.5 --- CONTRIBUTING.md | 4 ++-- lib/read-wasm-browser.js | 2 +- lib/url.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fbf90278..66e67b4f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,7 +40,7 @@ If you are filing an issue for a bug or other misbehavior, please provide: ## Building From Source -Install Node.js `12` or greater and then run +Install Node.js `18` or greater and then run $ git clone https://github.com/mozilla/source-map.git $ cd source-map/ @@ -65,7 +65,7 @@ force push to the remote branch to update the pull request. ## Running Tests -The test suite is written for node.js. Install node.js `12` or greater and +The test suite is written for node.js. Install node.js `18` or greater and then run the tests with `npm test`: ```shell diff --git a/lib/read-wasm-browser.js b/lib/read-wasm-browser.js index c7e13b3b..f245be6e 100644 --- a/lib/read-wasm-browser.js +++ b/lib/read-wasm-browser.js @@ -27,7 +27,7 @@ module.exports = function readWasm() { .then(glue => glue.default({ module_or_path: mappingsWasm }).then(() => glue) ) - .then(null, e => { + .catch(e => { cachedGlue = null; throw e; }); diff --git a/lib/url.js b/lib/url.js index 59c707b3..acb0d37d 100644 --- a/lib/url.js +++ b/lib/url.js @@ -6,7 +6,7 @@ */ "use strict"; -// `URL` has been a global since Node 10 and this package requires Node >= 12, +// `URL` has been a global since Node 10 and this package requires Node >= 18, // so there is no need to fall back to the 'url' core module. Requiring it would // also break bundlers that no longer polyfill Node core modules (webpack >= 5). module.exports = URL; From 456eae80658dfc47535beddfb1d1dfe25685d607 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Mon, 12 Oct 2026 05:20:46 +0100 Subject: [PATCH 18/18] Bring the contributing docs up to date - Drop the `npm run build` / dist/source-map.js instructions; there is no JS build step since dist/ was removed in #362. - Refresh the sample `npm test` output. - Pin wasm-pack 0.15.0 in the install command, matching CI. - Document the binaryen 132 requirement in wasm-mappings/CONTRIBUTING.md, which still claimed wasm-pack was the only tool needed. - Point wasm-pack links at wasm-bindgen.github.io; the rustwasm.github.io page is gone. Co-Authored-By: Claude Opus 5.5 --- CONTRIBUTING.md | 25 ++++++++++++------------- wasm-mappings/CONTRIBUTING.md | 16 +++++++++++----- wasm-mappings/build.sh | 2 +- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 66e67b4f..f4dbf346 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,13 +46,11 @@ Install Node.js `18` or greater and then run $ cd source-map/ $ npm install -Next, run - - $ npm run build - -This will create the following files: - -- `dist/source-map.js` - The plain browser build. +There is no build step for the JavaScript: the package is used directly from +`source-map.js` and `lib/`. The only generated files are `lib/mappings.wasm` and +its glue, which are committed; see +[Updating the `lib/mappings.wasm` WebAssembly Module](#updating-the-libmappingswasm-webassembly-module) +if you need to change them. ## Submitting Pull Requests @@ -70,11 +68,12 @@ then run the tests with `npm test`: ```shell $ npm test -> source-map@0.7.3 test /Users/fitzgen/src/source-map -> node test/run-tests.js + +> source-map@0.8.0 test +> git submodule update --init --recursive; node test/run-tests.js -137 / 137 tests passed. +190 / 190 tests passed. ``` ## Writing New Tests @@ -141,11 +140,11 @@ Note: The pin exists because CI rebuilds the committed artifacts and fails if they differ byte-for-byte, which only works if everyone builds with the same compiler. -Install [`wasm-pack`](https://rustwasm.github.io/wasm-pack/), which vendors -its own `wasm-bindgen`: +Install [`wasm-pack`](https://wasm-bindgen.github.io/wasm-pack/) version +0.15.0, the version CI uses, which vendors its own `wasm-bindgen`: ``` -$ cargo install wasm-pack +$ cargo install wasm-pack --version 0.15.0 --locked ``` You also need `wasm-opt` from [binaryen](https://github.com/WebAssembly/binaryen) diff --git a/wasm-mappings/CONTRIBUTING.md b/wasm-mappings/CONTRIBUTING.md index 1f54a686..c38841c3 100644 --- a/wasm-mappings/CONTRIBUTING.md +++ b/wasm-mappings/CONTRIBUTING.md @@ -15,15 +15,21 @@ directory: $ ./build.sh ``` -That runs [`wasm-pack`](https://rustwasm.github.io/wasm-pack/) twice -- once +That runs [`wasm-pack`](https://wasm-bindgen.github.io/wasm-pack/) twice -- once for the `nodejs` target and once for `web` -- and installs the results into `../lib/`. Both targets produce an identical `.wasm`; only the JS glue differs, and the script fails if they ever diverge. -`wasm-pack` is the only tool you need to install: it vendors its own -`wasm-bindgen` and `wasm-opt`. The toolchain version is pinned in -`rust-toolchain.toml`, including the `wasm32-unknown-unknown` target, so -`rustup` will fetch whatever is missing. +You need two tools besides Rust: + +- `wasm-pack` 0.15.0 (`cargo install wasm-pack --version 0.15.0 --locked`), + which vendors its own `wasm-bindgen`. +- `wasm-opt` from [binaryen](https://github.com/WebAssembly/binaryen) version + 132 on your `PATH`. `build.sh` refuses to run with any other version, because + without one wasm-pack downloads an older binaryen whose output differs. + +The Rust toolchain version is pinned in `rust-toolchain.toml`, including the +`wasm32-unknown-unknown` target, so `rustup` will fetch whatever is missing. Set `PROFILING=1` to enable the `profiling` cargo feature. diff --git a/wasm-mappings/build.sh b/wasm-mappings/build.sh index becd3e60..4fb1ab9c 100755 --- a/wasm-mappings/build.sh +++ b/wasm-mappings/build.sh @@ -2,7 +2,7 @@ # # Build `lib/mappings.wasm` and its wasm-bindgen glue. # -# Requires `wasm-pack` (https://rustwasm.github.io/wasm-pack/), which vendors +# Requires `wasm-pack` (https://wasm-bindgen.github.io/wasm-pack/), which vendors # its own `wasm-bindgen`, and binaryen's `wasm-opt` at exactly # $WASM_OPT_VERSION on PATH. wasm-pack prefers a `wasm-opt` from PATH and only # downloads its own (an older binaryen) when there is none, and different