From a3c7528858dd6a122b6073f5a3f0c2352b308017 Mon Sep 17 00:00:00 2001 From: Liam Potter Date: Sun, 19 Jul 2026 22:37:49 +0100 Subject: [PATCH] bench: update @tuananh/sax-parser to 1.4 and police arity probing 1.4 skips materializing event arguments for zero-arity listeners, which inflated its no-op benchmark numbers ~3x. The no-op callbacks now declare parameters so every parser materializes arguments, the work all JS parsers do unconditionally. With equal work, 1.4 is a genuine 1.6-2.8x improvement over 1.2 but stays behind eksml on every fixture. Tables, claims, and the native-addon note regenerated. --- eksml/BENCHMARKS.md | 144 +++++++++++++++++----------------- eksml/README.md | 4 +- eksml/bench/stream.bench.ts | 3 +- eksml/bench/tokenize.bench.ts | 7 +- eksml/package.json | 2 +- pnpm-lock.yaml | 90 ++++++++++----------- 6 files changed, 128 insertions(+), 122 deletions(-) diff --git a/eksml/BENCHMARKS.md b/eksml/BENCHMARKS.md index e33bdda..6158e18 100644 --- a/eksml/BENCHMARKS.md +++ b/eksml/BENCHMARKS.md @@ -105,66 +105,66 @@ Chunked streaming parse where each parser tokenizes SAX events and builds a full Eksml (SAX) - 95,408 op/s - 17,945 op/s - 13,932 op/s - 14,932 op/s - 13,431 op/s + 93,671 op/s + 17,666 op/s + 14,402 op/s + 14,708 op/s + 13,372 op/s easysax - 66,897 op/s - 14,591 op/s - 11,235 op/s - 10,517 op/s - 10,604 op/s + 61,700 op/s + 14,253 op/s + 11,063 op/s + 10,639 op/s + 10,204 op/s Eksml (XmlParseStream) - 30,549 op/s - 9,794 op/s - 8,947 op/s - 4,457 op/s - 8,690 op/s + 28,981 op/s + 9,531 op/s + 8,924 op/s + 4,670 op/s + 8,646 op/s htmlparser2 - 30,083 op/s - 7,384 op/s - 5,461 op/s - 6,912 op/s - 6,877 op/s + 28,402 op/s + 6,277 op/s + 5,386 op/s + 6,807 op/s + 6,802 op/s saxes - 26,185 op/s - 6,602 op/s - 6,780 op/s - 5,821 op/s - 5,634 op/s + 27,406 op/s + 6,519 op/s + 6,732 op/s + 5,510 op/s + 4,499 op/s - sax - 14,988 op/s - 3,561 op/s - 3,044 op/s - 3,806 op/s - 2,922 op/s + @tuananh/sax-parser + 25,737 op/s + 6,579 op/s + 6,085 op/s + 6,196 op/s + 4,189 op/s - @tuananh/sax-parser - 14,084 op/s - 3,918 op/s - 3,249 op/s - 2,394 op/s - 2,410 op/s + sax + 14,841 op/s + 3,550 op/s + 3,016 op/s + 3,792 op/s + 2,909 op/s -Eksml's SAX parser is **1.2-1.4x faster than easysax**, **2-3.6x faster than htmlparser2/saxes**, and **3.9-6.4x faster than sax**. +Eksml's SAX parser is **1.2-1.5x faster than easysax**, **2-3.4x faster than htmlparser2/saxes**, and **3.9-6.3x faster than sax**. > [!note] -> @tuananh/sax-parser is a native C++ addon; every `write()` crosses the JS↔C++ boundary, which dominates in chunked streaming. +> @tuananh/sax-parser is a native C++ addon; marshalling event arguments across the JS↔C++ boundary dominates its chunked-streaming cost. Since 1.4 it skips argument materialization for zero-arity listeners, so the no-op benchmark callbacks declare parameters — every other parser materializes arguments unconditionally, and the comparison requires equal work. ## Raw Tokenization (no-op callbacks) @@ -181,55 +181,55 @@ Pure scanner throughput with no downstream work -- isolates the tokenizer's raw Eksml (SAX) - 104,122 op/s - 20,970 op/s - 19,927 op/s - 17,063 op/s - 15,605 op/s + 113,482 op/s + 20,462 op/s + 18,506 op/s + 17,186 op/s + 17,462 op/s easysax - 73,389 op/s - 15,678 op/s - 11,899 op/s - 11,982 op/s - 11,933 op/s + 74,171 op/s + 15,868 op/s + 12,637 op/s + 11,124 op/s + 11,316 op/s saxes - 35,355 op/s - 9,492 op/s - 7,290 op/s - 8,870 op/s - 8,562 op/s + 33,493 op/s + 9,434 op/s + 8,241 op/s + 7,690 op/s + 7,885 op/s htmlparser2 - 30,520 op/s - 7,647 op/s - 6,334 op/s - 6,475 op/s - 7,145 op/s + 28,743 op/s + 7,347 op/s + 6,309 op/s + 7,122 op/s + 7,081 op/s - sax - 15,307 op/s - 3,679 op/s - 3,184 op/s - 3,928 op/s - 3,315 op/s + @tuananh/sax-parser + 27,172 op/s + 7,496 op/s + 6,145 op/s + 6,001 op/s + 5,036 op/s - @tuananh/sax-parser - 12,907 op/s - 4,197 op/s - 3,217 op/s - 2,388 op/s - 2,608 op/s + sax + 15,458 op/s + 3,997 op/s + 2,945 op/s + 3,664 op/s + 3,252 op/s -Eksml's tokenizer is **1.3-1.7x faster than easysax**, **1.8-3.4x faster than saxes/htmlparser2**, and **4.3-6.8x faster than sax**. +Eksml's tokenizer is **1.3-1.6x faster than easysax**, **2.2-4x faster than saxes/htmlparser2**, and **4.7-7.3x faster than sax**. > [!note] > easysax parses attributes lazily (`startNode` receives a `getAttr()` thunk); the benchmark invokes it so every parser materializes attributes, the work all other parsers do unconditionally for their open-tag events. diff --git a/eksml/README.md b/eksml/README.md index 854fc7d..8a03328 100644 --- a/eksml/README.md +++ b/eksml/README.md @@ -534,8 +534,8 @@ import { Eksml is consistently the fastest at parsing, streaming, and tokenization, and leads serialization with `validate: false`. Benchmarks run via [Vitest bench](https://vitest.dev/guide/features.html#benchmarking) against real-world XML fixtures from ~100 B to ~30 KB, plus a synthetic attribute-heavy stress document. - **DOM parsing**: 1.7-2.2x faster than tXml, 3-6x faster than htmlparser2, 10-25x faster than fast-xml-parser/xml2js/xmldom -- **SAX streaming**: 1.2-1.4x faster than easysax, 2-3.6x faster than htmlparser2/saxes, 3.9-6.4x faster than sax -- **Raw tokenization**: 1.3-1.7x faster than easysax, 1.8-3.4x faster than saxes/htmlparser2, 4.3-6.8x faster than sax +- **SAX streaming**: 1.2-1.5x faster than easysax, 2-3.4x faster than htmlparser2/saxes, 3.9-6.3x faster than sax +- **Raw tokenization**: 1.3-1.6x faster than easysax, 2.2-4x faster than saxes/htmlparser2, 4.7-7.3x faster than sax - **Serialization**: Fastest on every fixture with `validate: false`; with validation on (the default), wins RSS/SOAP/Atom/POM while tXml edges small/EPG; 2-7x faster than xmldom and 7-19x faster than fast-xml-parser/xml2js Full results with per-fixture op/s tables: **[BENCHMARKS.md](https://github.com/evoactivity/eksml/blob/main/eksml/BENCHMARKS.md)** diff --git a/eksml/bench/stream.bench.ts b/eksml/bench/stream.bench.ts index 1df6b97..939f5d5 100644 --- a/eksml/bench/stream.bench.ts +++ b/eksml/bench/stream.bench.ts @@ -238,7 +238,8 @@ tuananhParser.on('text', (text: string) => { tuananhParser.on('cdata', (cdata: string) => { pushChild(cdata); }); -tuananhParser.on('endElement', () => { +// Parameter declared so arity probing cannot skip materializing the name +tuananhParser.on('endElement', (_name: string) => { stack.pop(); }); diff --git a/eksml/bench/tokenize.bench.ts b/eksml/bench/tokenize.bench.ts index a790fb8..62afeaa 100644 --- a/eksml/bench/tokenize.bench.ts +++ b/eksml/bench/tokenize.bench.ts @@ -66,7 +66,12 @@ const xmltvChunks64 = chunkString(xmltvEpg, 64); const attrHeavyChunks256 = chunkString(attrHeavy, 256); // No-op function used as callback -const noop = () => {}; +// No-op callback with DECLARED parameters. Some parsers probe listener arity +// (Function.length) and skip materializing event arguments for zero-arity +// handlers (@tuananh/sax-parser 1.4 inflates ~3x this way). Every JS parser +// here materializes arguments unconditionally, so the no-op declares +// parameters to keep the measured work equal. +const noop = (_a?: unknown, _b?: unknown) => {}; // --------------------------------------------------------------------------- // eksml createSaxParser — persistent parser, no-op callbacks (close() resets) diff --git a/eksml/package.json b/eksml/package.json index ab4be07..7aa4143 100644 --- a/eksml/package.json +++ b/eksml/package.json @@ -82,7 +82,7 @@ "license": "MIT", "packageManager": "pnpm@10.33.0", "devDependencies": { - "@tuananh/sax-parser": "^1.2.0", + "@tuananh/sax-parser": "^1.4.0", "@types/node": "^25.5.0", "@types/sax": "^1.2.7", "@types/xml2js": "^0.4.14", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3823fb9..0fc18ae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -149,8 +149,8 @@ importers: version: 8.0.0 devDependencies: '@tuananh/sax-parser': - specifier: ^1.2.0 - version: 1.2.0 + specifier: ^1.4.0 + version: 1.4.0 '@types/node': specifier: ^25.5.0 version: 25.5.0 @@ -1580,60 +1580,60 @@ packages: resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} - '@tuananh/sax-parser-darwin-arm64@1.2.0': - resolution: {integrity: sha512-epRwVplpKMLYtIaTpOkuIXXeI+aM6N0W7m7MPDIJcwbAXu2m9qmGCl84senxr8gc1YnjvNN5drxoHQBwgQOtMQ==} + '@tuananh/sax-parser-darwin-arm64@1.4.0': + resolution: {integrity: sha512-PRT9p0PiYc9n1TfKypxq3g19uej/bTjAQ9FOENdEsnImtfZx3MheBKlZOVp1BVcjZb/uo6oBMyR2FOrf4ddclA==} engines: {node: '>= 18'} cpu: [arm64] os: [darwin] - '@tuananh/sax-parser-darwin-x64@1.2.0': - resolution: {integrity: sha512-Q1QT7oebbnn2yz1/NthQm4svyZCbKyKI2OgqA/iQVUx08dj3v+yCiNHkWqgTPNkpZQdpLeOlCLQdmX1RiFd4Xg==} + '@tuananh/sax-parser-darwin-x64@1.4.0': + resolution: {integrity: sha512-Dy9obEHGoKpcJy9xu0nyCahIOGhgNQYJFqoUGwQVgU0nrfXra228LvdDK1dlCyJvBh43N2XzUSube2Pmw0oR1Q==} engines: {node: '>= 18'} cpu: [x64] os: [darwin] - '@tuananh/sax-parser-linux-arm64-gnu@1.2.0': - resolution: {integrity: sha512-Prodgbi4GV9+r+dWfvX2Hka24lJgjWTFTm5rSGc4VCjQ+72FGtHbt5+0RksqNYamlwl+xVHNTcjli0bK4wxjrQ==} + '@tuananh/sax-parser-linux-arm64-gnu@1.4.0': + resolution: {integrity: sha512-2k6Dq2lOma0f8miPF8LMW+VUxu/xRWyc4UAYFg2y06BLVmJVurgfrXayT2BS4bWw8f2WS4U2EikDLKWcjUu+1g==} engines: {node: '>= 18'} cpu: [arm64] os: [linux] libc: [glibc] - '@tuananh/sax-parser-linux-arm64-musl@1.2.0': - resolution: {integrity: sha512-1HAUzy6yMr38+3PEOv0s1k0LC5cnXAXXoL6RMTc2P/T71zVlN4y4ReUw6Eewvk8a8ePkV1DwN5QLiavVPtvniQ==} + '@tuananh/sax-parser-linux-arm64-musl@1.4.0': + resolution: {integrity: sha512-0RdDHE8e2tKYIzlrpA2gbchymySHqsngWqo1AW6tNfEX/dRhbsgvX1vt7lS6g0i9KYfwHZ3hkQBkWWGRZbLQTQ==} engines: {node: '>= 18'} cpu: [arm64] os: [linux] libc: [musl] - '@tuananh/sax-parser-linux-x64-gnu@1.2.0': - resolution: {integrity: sha512-qbOL6zfS5VVmK/IeTMiJDe7gqUjrVMCCBr+0LryKAzW424SPDsH8zmkvJrKwHEu+NIAJu5WyTbuzSebKUFANFA==} + '@tuananh/sax-parser-linux-x64-gnu@1.4.0': + resolution: {integrity: sha512-38lWUrgwn+yw2yIEFbx9JQf+YayNW9SBwY6dkO1jnQuzsB9EGD4aQr9WmkdXD2agos3xpSJT4TtHe9PElC0d1A==} engines: {node: '>= 18'} cpu: [x64] os: [linux] libc: [glibc] - '@tuananh/sax-parser-linux-x64-musl@1.2.0': - resolution: {integrity: sha512-iO00t6nSgDe4Kk63lUNq8nV6v+aO0L7e6fojMLRwbrO22k5V98IQDYpOn6LHiePf1zFeeRUJ662Q1qp5dbB8Mw==} + '@tuananh/sax-parser-linux-x64-musl@1.4.0': + resolution: {integrity: sha512-7+fR76kdubwUr5iZ0JpKh3sKigtYY2ScEpd8/bnehQWsOYofP20VtU6j6Zj2no7j2KkbLZwUmkmZrmffACmBow==} engines: {node: '>= 18'} cpu: [x64] os: [linux] libc: [musl] - '@tuananh/sax-parser-win32-arm64-msvc@1.2.0': - resolution: {integrity: sha512-p28xhPsfBMMoUo2h0PkHXjxN1G2pMCe0ACfNB1nsySgr0N9G/edKE+dBsNBnulwVJpWcHwq0GzSDpCw1bIXVtQ==} + '@tuananh/sax-parser-win32-arm64-msvc@1.4.0': + resolution: {integrity: sha512-m8Y0CC/iFMMEhpeZuI0sjQmffBZZ6W46wqrjW33Uif4iCS4iOus5qtXd16KaD7kcPbRx2UhMg12dgDtKkaCqww==} engines: {node: '>= 18'} cpu: [arm64] os: [win32] - '@tuananh/sax-parser-win32-x64-msvc@1.2.0': - resolution: {integrity: sha512-LKxGbvDhwQJHZZXYqAxEP/MnRmGsMQVggg1L/y+O4GdCJ7akucwRiTEuk8ol/GKimuUWzPFSXhNIm4m+RNDU3Q==} + '@tuananh/sax-parser-win32-x64-msvc@1.4.0': + resolution: {integrity: sha512-Q+4UC7DYe1ACD6B5Cbzn7GRQQPl1RrdxWz1nMatQoYemsOcCGwBy1ms4B0d0WEVouf2ERDhPaWOJenER0JNQww==} engines: {node: '>= 18'} cpu: [x64] os: [win32] - '@tuananh/sax-parser@1.2.0': - resolution: {integrity: sha512-YmcxRNApC5M9g+OeounLl/8M6prrKH/hI4HALRTdS2heO718r431g0FuNiw3Fe4EQllwtE27LLJHptLXUA3+kw==} + '@tuananh/sax-parser@1.4.0': + resolution: {integrity: sha512-UxdyMxSkCuRg0km8hGfhcH3LROe/1iljMvZzOFxXrOXxJqpDYGIciUB1quTPLZ9X3lShSDiuJkKJDs0dIID8Rg==} engines: {node: '>= 18'} '@tybys/wasm-util@0.10.1': @@ -6475,9 +6475,9 @@ snapshots: cosmiconfig: 9.0.1(typescript@6.0.2) ember-eslint: 0.6.1(@babel/core@7.29.0)(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) eslint: 9.39.4(jiti@2.6.1) - eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) + eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-decorator-position: 6.0.0(@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-json: 4.0.1 eslint-plugin-n: 17.24.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) eslint-plugin-simple-import-sort: 12.1.1(eslint@9.39.4(jiti@2.6.1)) @@ -6744,44 +6744,44 @@ snapshots: '@tootallnate/once@1.1.2': {} - '@tuananh/sax-parser-darwin-arm64@1.2.0': + '@tuananh/sax-parser-darwin-arm64@1.4.0': optional: true - '@tuananh/sax-parser-darwin-x64@1.2.0': + '@tuananh/sax-parser-darwin-x64@1.4.0': optional: true - '@tuananh/sax-parser-linux-arm64-gnu@1.2.0': + '@tuananh/sax-parser-linux-arm64-gnu@1.4.0': optional: true - '@tuananh/sax-parser-linux-arm64-musl@1.2.0': + '@tuananh/sax-parser-linux-arm64-musl@1.4.0': optional: true - '@tuananh/sax-parser-linux-x64-gnu@1.2.0': + '@tuananh/sax-parser-linux-x64-gnu@1.4.0': optional: true - '@tuananh/sax-parser-linux-x64-musl@1.2.0': + '@tuananh/sax-parser-linux-x64-musl@1.4.0': optional: true - '@tuananh/sax-parser-win32-arm64-msvc@1.2.0': + '@tuananh/sax-parser-win32-arm64-msvc@1.4.0': optional: true - '@tuananh/sax-parser-win32-x64-msvc@1.2.0': + '@tuananh/sax-parser-win32-x64-msvc@1.4.0': optional: true - '@tuananh/sax-parser@1.2.0': + '@tuananh/sax-parser@1.4.0': dependencies: bindings: 1.5.0 detect-libc: 2.1.2 node-addon-api: 8.9.0 optionalDependencies: - '@tuananh/sax-parser-darwin-arm64': 1.2.0 - '@tuananh/sax-parser-darwin-x64': 1.2.0 - '@tuananh/sax-parser-linux-arm64-gnu': 1.2.0 - '@tuananh/sax-parser-linux-arm64-musl': 1.2.0 - '@tuananh/sax-parser-linux-x64-gnu': 1.2.0 - '@tuananh/sax-parser-linux-x64-musl': 1.2.0 - '@tuananh/sax-parser-win32-arm64-msvc': 1.2.0 - '@tuananh/sax-parser-win32-x64-msvc': 1.2.0 + '@tuananh/sax-parser-darwin-arm64': 1.4.0 + '@tuananh/sax-parser-darwin-x64': 1.4.0 + '@tuananh/sax-parser-linux-arm64-gnu': 1.4.0 + '@tuananh/sax-parser-linux-arm64-musl': 1.4.0 + '@tuananh/sax-parser-linux-x64-gnu': 1.4.0 + '@tuananh/sax-parser-linux-x64-musl': 1.4.0 + '@tuananh/sax-parser-win32-arm64-msvc': 1.4.0 + '@tuananh/sax-parser-win32-x64-msvc': 1.4.0 '@tybys/wasm-util@0.10.1': dependencies: @@ -8105,7 +8105,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)): + eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) @@ -8116,18 +8116,18 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2) eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) + eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -8170,7 +8170,7 @@ snapshots: eslint: 9.39.4(jiti@2.6.1) eslint-compat-utils: 0.5.1(eslint@9.39.4(jiti@2.6.1)) - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -8181,7 +8181,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.4(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.2))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3