diff --git a/README.md b/README.md index 1b69d35..85696d0 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,8 @@ so let us know if it doesn't work for your use case The BAM class constructor accepts arguments -- `bamPath`/`bamUrl`/`bamFilehandle` - a string file path to a local file or a - class object with a read method +- `bamPath`/`bamUrl`/`bamFilehandle` - a local file path, remote URL string, or + a class object with a read method - `csiPath`/`csiUrl`/`csiFilehandle` - a CSI index for the BAM file, required for long chromosomes greater than 2^29 in length - `baiPath`/`baiUrl`/`baiFilehandle` - a BAI index for the BAM file @@ -112,8 +112,8 @@ density across 16kb windows in the genome - `refName` - a string for the chrom to fetch from Returns number of features on refName, uses special pseudo-bin from the BAI/CSI -index (e.g. bin 37450 from bai, returning n_mapped from SAM spec pdf) or -1 if -refName not exist in sample +index (e.g. bin 37450 from bai, returning n_mapped from SAM spec pdf) or 0 if +refName does not exist in the sample ### async hasRefSeq(refName: string) @@ -201,3 +201,12 @@ console.log(records[0].getDoubleStart()) ## License MIT © [Colin Diesh](https://github.com/cmdcolin) + +## Publishing + +[Trusted publishing](https://docs.npmjs.com/about-trusted-publishing) via GitHub +Actions. + +```bash +npm version patch # or minor/major +``` diff --git a/benchmarks/cigar-parsing.bench.ts b/benchmarks/cigar-parsing.bench.ts deleted file mode 100644 index 20237b4..0000000 --- a/benchmarks/cigar-parsing.bench.ts +++ /dev/null @@ -1,240 +0,0 @@ -import { bench, describe } from 'vitest' - -// CIGAR operation constants -const CIGAR_INS = 1 -const CIGAR_SOFT_CLIP = 4 -const CIGAR_HARD_CLIP = 5 - -const CIGAR_SKIP_MASK = - (1 << CIGAR_INS) | (1 << CIGAR_SOFT_CLIP) | (1 << CIGAR_HARD_CLIP) - -const CIGAR_CONSUMES_REF_MASK = 0x1cd - -const CIGAR_CONSUMES_REF_TABLE = new Int32Array([ - 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, -]) - -// Generate test CIGAR data (mix of ops that do/don't consume ref) -function generateCigarData(numOps: number, aligned: boolean) { - const padding = aligned ? 0 : 1 - const buffer = new ArrayBuffer(padding + numOps * 4 + 4) - const view = new DataView(buffer) - - for (let i = 0; i < numOps; i++) { - // Random op (0-8), random length (1-1000) - const op = Math.floor(Math.random() * 9) - const len = Math.floor(Math.random() * 1000) + 1 - const cigop = (len << 4) | op - view.setInt32(padding + i * 4, cigop, true) - } - - return { - byteArray: new Uint8Array(buffer, padding), - dataView: new DataView(buffer, padding), - buffer, - offset: padding, - numOps, - } -} - -// Approach 1: Original - DataView.getInt32 + branch -function originalApproach( - dataView: DataView, - numOps: number, -): { lref: number; cigar: number[] } { - const cigarArray: number[] = new Array(numOps) - let lref = 0 - for (let c = 0; c < numOps; ++c) { - const cigop = dataView.getInt32(c * 4, true) | 0 - cigarArray[c] = cigop - const op = (cigop & 0xf) | 0 - if (!((1 << op) & CIGAR_SKIP_MASK)) { - lref = (lref + (cigop >> 4)) | 0 - } - } - return { lref, cigar: cigarArray } -} - -// Approach 2: Direct byte access + bitmask -function directBytesBitmask( - byteArray: Uint8Array, - numOps: number, -): { lref: number; cigar: number[] } { - const cigarArray: number[] = new Array(numOps) - let lref = 0 - for (let c = 0; c < numOps; ++c) { - const offset = c * 4 - const cigop = - byteArray[offset]! | - (byteArray[offset + 1]! << 8) | - (byteArray[offset + 2]! << 16) | - (byteArray[offset + 3]! << 24) | - 0 - cigarArray[c] = cigop - lref += (cigop >> 4) * ((CIGAR_CONSUMES_REF_MASK >> (cigop & 0xf)) & 1) - } - return { lref, cigar: cigarArray } -} - -// Approach 3: Direct byte access + lookup table -function directBytesLookup( - byteArray: Uint8Array, - numOps: number, -): { lref: number; cigar: number[] } { - const cigarArray: number[] = new Array(numOps) - let lref = 0 - for (let c = 0; c < numOps; ++c) { - const offset = c * 4 - const cigop = - byteArray[offset]! | - (byteArray[offset + 1]! << 8) | - (byteArray[offset + 2]! << 16) | - (byteArray[offset + 3]! << 24) | - 0 - cigarArray[c] = cigop - lref += (cigop >> 4) * CIGAR_CONSUMES_REF_TABLE[cigop & 0xf]! - } - return { lref, cigar: cigarArray } -} - -// Approach 4: DataView + bitmask (hybrid) -function dataViewBitmask( - dataView: DataView, - numOps: number, -): { lref: number; cigar: number[] } { - const cigarArray: number[] = new Array(numOps) - let lref = 0 - for (let c = 0; c < numOps; ++c) { - const cigop = dataView.getInt32(c * 4, true) | 0 - cigarArray[c] = cigop - lref += (cigop >> 4) * ((CIGAR_CONSUMES_REF_MASK >> (cigop & 0xf)) & 1) - } - return { lref, cigar: cigarArray } -} - -// Approach 5: Uint32Array view (only works for aligned data) -function uint32ViewBitmask( - buffer: ArrayBuffer, - offset: number, - numOps: number, -): { lref: number; cigar: Uint32Array } { - const cigarView = new Uint32Array(buffer, offset, numOps) - let lref = 0 - for (let c = 0; c < numOps; ++c) { - const cigop = cigarView[c]! - lref += (cigop >> 4) * ((CIGAR_CONSUMES_REF_MASK >> (cigop & 0xf)) & 1) - } - return { lref, cigar: cigarView } -} - -// Approach 6: Uint32Array slice+copy (works for unaligned) -function uint32SliceCopy( - byteArray: Uint8Array, - numOps: number, -): { lref: number; cigar: Uint32Array } { - const copy = byteArray.slice(0, numOps * 4) - const cigarView = new Uint32Array(copy.buffer, copy.byteOffset, numOps) - let lref = 0 - for (let c = 0; c < numOps; ++c) { - const cigop = cigarView[c]! - lref += (cigop >> 4) * ((CIGAR_CONSUMES_REF_MASK >> (cigop & 0xf)) & 1) - } - return { lref, cigar: cigarView } -} - -function benchCigarSize(name: string, numOps: number, iterations: number) { - const alignedData = generateCigarData(numOps, true) - const unalignedData = generateCigarData(numOps, false) - - describe(`${name} - aligned`, () => { - bench( - 'original (DataView + branch)', - () => { - originalApproach(alignedData.dataView, numOps) - }, - { iterations }, - ) - - bench( - 'DataView + bitmask', - () => { - dataViewBitmask(alignedData.dataView, numOps) - }, - { iterations }, - ) - - bench( - 'direct bytes + bitmask', - () => { - directBytesBitmask(alignedData.byteArray, numOps) - }, - { iterations }, - ) - - bench( - 'direct bytes + lookup table', - () => { - directBytesLookup(alignedData.byteArray, numOps) - }, - { iterations }, - ) - - bench( - 'Uint32Array view + bitmask', - () => { - uint32ViewBitmask(alignedData.buffer, alignedData.offset, numOps) - }, - { iterations }, - ) - }) - - describe(`${name} - unaligned`, () => { - bench( - 'original (DataView + branch)', - () => { - originalApproach(unalignedData.dataView, numOps) - }, - { iterations }, - ) - - bench( - 'DataView + bitmask', - () => { - dataViewBitmask(unalignedData.dataView, numOps) - }, - { iterations }, - ) - - bench( - 'direct bytes + bitmask', - () => { - directBytesBitmask(unalignedData.byteArray, numOps) - }, - { iterations }, - ) - - bench( - 'direct bytes + lookup table', - () => { - directBytesLookup(unalignedData.byteArray, numOps) - }, - { iterations }, - ) - - bench( - 'Uint32Array slice+copy + bitmask', - () => { - uint32SliceCopy(unalignedData.byteArray, numOps) - }, - { iterations }, - ) - }) -} - -// Test various CIGAR sizes -benchCigarSize('tiny (3 ops)', 3, 50000) -benchCigarSize('small (10 ops)', 10, 50000) -benchCigarSize('medium (50 ops)', 50, 20000) -benchCigarSize('large (200 ops)', 200, 10000) -benchCigarSize('huge (1000 ops)', 1000, 2000) -benchCigarSize('extreme (10000 ops)', 10000, 500) diff --git a/eslint.config.mjs b/eslint.config.mjs index 3805e04..04f77da 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,12 +1,13 @@ import eslint from '@eslint/js' import { defineConfig } from 'eslint/config' -import importPlugin from 'eslint-plugin-import' +import importPlugin from 'eslint-plugin-import-x' import eslintPluginUnicorn from 'eslint-plugin-unicorn' import tseslint from 'typescript-eslint' export default defineConfig( { ignores: [ + 'scripts', 'webpack.config.js', 'benchmarks/*', 'dist/*', @@ -119,9 +120,9 @@ export default defineConfig( }, ], - 'import/extensions': ['error', 'ignorePackages'], - 'import/no-unresolved': 'off', - 'import/order': [ + 'import-x/extensions': ['error', 'ignorePackages'], + 'import-x/no-unresolved': 'off', + 'import-x/order': [ 'error', { named: true, diff --git a/package.json b/package.json index 106e266..1609569 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,10 @@ "url": "https://github.com/GMOD/bam-js.git" }, "type": "module", - "types": "./esm/index.d.ts", + "main": "dist/index.js", "exports": { - ".": { - "import": "./esm/index.js", - "require": "./dist/index.js" - } + "import": "./esm/index.js", + "require": "./dist/index.js" }, "author": { "name": "Colin Diesh", @@ -27,19 +25,19 @@ ], "scripts": { "test": "vitest", - "benchonly": "vitest bench", - "bench": "./scripts/build-both-branches.sh \"$BRANCH1\" \"$BRANCH2\" && vitest bench", - "lint": "eslint --report-unused-disable-directives --max-warnings 0", "clean": "rimraf dist esm", "format": "prettier --write .", + "lint": "eslint --report-unused-disable-directives --max-warnings 0", + "prebuild": "pnpm clean", "build:esm": "tsc --outDir esm", "build:es5": "tsc --module commonjs --moduleResolution bundler --outDir dist", - "build": "pnpm build:esm && pnpm build:es5", - "prebuild": "pnpm clean", "postbuild:es5": "echo '{\"type\": \"commonjs\"}' > dist/package.json", "preversion": "pnpm lint && pnpm test --run && pnpm build", - "version": "standard-changelog && git add CHANGELOG.md", - "postversion": "git push --follow-tags" + "postversion": "git push --follow-tags", + "build": "pnpm build:esm && pnpm build:es5", + "benchonly": "vitest bench", + "bench": "./scripts/build-both-branches.sh \"$BRANCH1\" \"$BRANCH2\" && vitest bench", + "version": "standard-changelog && git add CHANGELOG.md" }, "keywords": [ "bionode", @@ -58,7 +56,7 @@ "@types/node": "^25.6.0", "@vitest/coverage-v8": "^4.1.5", "eslint": "^10.2.1", - "eslint-plugin-import": "^2.32.0", + "eslint-plugin-import-x": "^4.16.2", "eslint-plugin-unicorn": "^64.0.0", "prettier": "^3.8.3", "rimraf": "^6.1.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 47dc26d..ec81d1e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,9 +33,9 @@ importers: eslint: specifier: ^10.2.1 version: 10.2.1 - eslint-plugin-import: - specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.59.0(eslint@10.2.1)(typescript@6.0.3))(eslint@10.2.1) + eslint-plugin-import-x: + specifier: ^4.16.2 + version: 4.16.2(@typescript-eslint/utils@8.59.0(eslint@10.2.1)(typescript@6.0.3))(eslint@10.2.1) eslint-plugin-unicorn: specifier: ^64.0.0 version: 64.0.0(eslint@10.2.1) @@ -93,6 +93,15 @@ packages: conventional-commits-parser: optional: true + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@esbuild/aix-ppc64@0.27.7': resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} engines: {node: '>=18'} @@ -325,6 +334,12 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@package-json/types@0.0.12': + resolution: {integrity: sha512-uu43FGU34B5VM9mCNjXCwLaGHYjXdNincqKLaraaCW+7S2+SmiBg1Nv8bPnmschrIfZmfKNY9f3fC376MRrObw==} + '@rollup/rollup-android-arm-eabi@4.60.2': resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} cpu: [arm] @@ -463,9 +478,6 @@ packages: cpu: [x64] os: [win32] - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@simple-libs/child-process-utils@1.0.2': resolution: {integrity: sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==} engines: {node: '>=18'} @@ -481,6 +493,9 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -496,9 +511,6 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/json5@0.0.29': - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/node@25.6.0': resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} @@ -564,6 +576,109 @@ packages: resolution: {integrity: sha512-/uejZt4dSere1bx12WLlPfv8GktzcaDtuJ7s42/HEZ5zGj9oxRaD4bj7qwSunXkf+pbAhFt2zjpHYUiT5lHf0Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + '@vitest/coverage-v8@4.1.5': resolution: {integrity: sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A==} peerDependencies: @@ -615,33 +730,9 @@ packages: ajv@6.15.0: resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -649,17 +740,6 @@ packages: ast-v8-to-istanbul@1.0.0: resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==} - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -669,9 +749,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - brace-expansion@1.1.14: - resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} - brace-expansion@5.0.5: resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} @@ -685,18 +762,6 @@ packages: resolution: {integrity: sha512-c5JxaDrzwRjq3WyJkI1AGR5xy6Gr6udlt7sQPbl09+3ckB+Zo2qqQ2KhCTBr7Q8dHB43bENGYEk4xddrFH/b7A==} engines: {node: '>=18.20'} - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.9: - resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - caniuse-lite@1.0.30001790: resolution: {integrity: sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==} @@ -715,12 +780,13 @@ packages: resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} engines: {node: '>=4'} + comment-parser@1.4.6: + resolution: {integrity: sha512-ObxuY6vnbWTN6Od72xfwN9DbzC7Y2vv8u1Soi9ahRKL37gb6y1qk6/dgjs+3JWuXJHWvsg3BXIwzd/rkmAwavg==} + engines: {node: '>= 12.0.0'} + compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - conventional-changelog-angular@8.3.1: resolution: {integrity: sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==} engines: {node: '>=18'} @@ -767,26 +833,6 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -799,64 +845,20 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - electron-to-chromium@1.5.344: resolution: {integrity: sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==} - es-abstract@1.24.2: - resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - es-module-lexer@2.0.0: resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} - esbuild@0.27.7: resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} @@ -874,38 +876,26 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-import-resolver-node@0.3.10: - resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} - - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} - engines: {node: '>=4'} + eslint-import-context@0.1.9: + resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' + unrs-resolver: ^1.0.0 peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: + unrs-resolver: optional: true - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} - engines: {node: '>=4'} + eslint-plugin-import-x@4.16.2: + resolution: {integrity: sha512-rM9K8UBHcWKpzQzStn1YRN2T5NvdeIfSVoKu/lKF41znQXHAUcBbYXe5wd6GNjZjTrP7viQ49n1D83x/2gYgIw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + '@typescript-eslint/utils': ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + eslint-import-resolver-node: '*' peerDependenciesMeta: - '@typescript-eslint/parser': + '@typescript-eslint/utils': + optional: true + eslint-import-resolver-node: optional: true eslint-plugin-unicorn@64.0.0: @@ -1003,44 +993,17 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - - generator-function@2.0.1: - resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} - engines: {node: '>= 0.4'} - generic-filehandle2@2.1.4: resolution: {integrity: sha512-v50AM/0Ei8RkhLCGHE4QrxEdxX53pjnZCrPaO+yvTGZfFQjCeHcULBl8Qw1bmnGHj/eOOTMwLpW1zuZY3eQ1rA==} engines: {node: '>=14'} - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} @@ -1054,46 +1017,15 @@ packages: resolution: {integrity: sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==} engines: {node: '>=18'} - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - handlebars@4.7.9: resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} engines: {node: '>=0.4.7'} hasBin: true - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} - engines: {node: '>= 0.4'} - hosted-git-info@8.1.0: resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} engines: {node: ^18.17.0 || >=20.5.0} @@ -1117,117 +1049,22 @@ packages: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} - - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} - - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} - - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} - is-builtin-module@5.0.0: resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} engines: {node: '>=18.20'} - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} - - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} - - is-generator-function@1.1.2: - resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} - engines: {node: '>= 0.4'} - is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} - is-obj@2.0.0: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} - - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} - - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1260,10 +1097,6 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1366,10 +1199,6 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - meow@13.2.0: resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} engines: {node: '>=18'} @@ -1378,9 +1207,6 @@ packages: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} - minimatch@3.1.5: - resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -1396,16 +1222,17 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - node-exports-info@1.6.0: - resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} - engines: {node: '>= 0.4'} - node-releases@2.0.38: resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} @@ -1413,34 +1240,6 @@ packages: resolution: {integrity: sha512-linxNAT6M0ebEYZOx2tO6vBEFsVgnPpv+AVjk0wJHfaUIbq31Jm3T6vvZaarnOeWDh8ShnwXuaAyM7WT3RzErA==} engines: {node: ^18.17.0 || >=20.5.0} - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} @@ -1448,10 +1247,6 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} - p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -1474,9 +1269,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.2: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} @@ -1495,10 +1287,6 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - postcss@8.5.10: resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} engines: {node: ^10 || ^12 || >=14} @@ -1516,26 +1304,16 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} - regexp-tree@0.1.27: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} - regjsparser@0.13.1: resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} hasBin: true - resolve@2.0.0-next.6: - resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} - engines: {node: '>= 0.4'} - hasBin: true + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} rimraf@6.1.3: resolution: {integrity: sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==} @@ -1547,39 +1325,11 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - safe-array-concat@1.1.4: - resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} - engines: {node: '>=0.4'} - - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - semver@7.7.4: resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} hasBin: true - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1588,22 +1338,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -1627,6 +1361,10 @@ packages: spdx-license-ids@3.0.23: resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + stable-hash-x@0.2.0: + resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + engines: {node: '>=12.0.0'} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -1638,26 +1376,6 @@ packages: std-env@4.1.0: resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} - - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - strip-indent@4.1.1: resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} engines: {node: '>=12'} @@ -1666,10 +1384,6 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -1691,29 +1405,13 @@ packages: peerDependencies: typescript: '>=4.8.4' - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} - typescript-eslint@8.59.0: resolution: {integrity: sha512-BU3ONW9X+v90EcCH9ZS6LMackcVtxRLlI3XrYyqZIwVSHIk7Qf7bFw1z0M9Q0IUxhTMZCf8piY9hTYaNEIASrw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1731,13 +1429,12 @@ packages: engines: {node: '>=0.8.0'} hasBin: true - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} - undici-types@7.19.2: resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -1835,22 +1532,6 @@ packages: resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} engines: {node: 20 || >=22} - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} - - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} - - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.20: - resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} - engines: {node: '>= 0.4'} - which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1898,6 +1579,22 @@ snapshots: conventional-commits-filter: 5.0.0 conventional-commits-parser: 6.4.0 + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.27.7': optional: true @@ -2043,6 +1740,15 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@package-json/types@0.0.12': {} + '@rollup/rollup-android-arm-eabi@4.60.2': optional: true @@ -2118,8 +1824,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.60.2': optional: true - '@rtsao/scc@1.1.0': {} - '@simple-libs/child-process-utils@1.0.2': dependencies: '@simple-libs/stream-utils': 1.2.0 @@ -2130,6 +1834,11 @@ snapshots: '@standard-schema/spec@1.1.0': {} + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 @@ -2143,8 +1852,6 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/json5@0.0.29': {} - '@types/node@25.6.0': dependencies: undici-types: 7.19.2 @@ -2242,6 +1949,65 @@ snapshots: '@typescript-eslint/types': 8.59.0 eslint-visitor-keys: 5.0.1 + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + '@vitest/coverage-v8@4.1.5(vitest@4.1.5)': dependencies: '@bcoe/v8-coverage': 1.0.2 @@ -2310,58 +2076,8 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - array-buffer-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - is-array-buffer: 3.0.5 - array-ify@1.0.0: {} - array-includes@3.1.9: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - - array.prototype.findlastindex@1.2.6: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-shim-unscopables: 1.1.0 - - arraybuffer.prototype.slice@1.0.4: - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.5 - assertion-error@2.0.1: {} ast-v8-to-istanbul@1.0.0: @@ -2370,23 +2086,10 @@ snapshots: estree-walker: 3.0.3 js-tokens: 10.0.0 - async-function@1.0.0: {} - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - - balanced-match@1.0.2: {} - balanced-match@4.0.4: {} baseline-browser-mapping@2.10.21: {} - brace-expansion@1.1.14: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - brace-expansion@5.0.5: dependencies: balanced-match: 4.0.4 @@ -2401,23 +2104,6 @@ snapshots: builtin-modules@5.1.0: {} - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.9: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - caniuse-lite@1.0.30001790: {} chai@6.2.2: {} @@ -2430,13 +2116,13 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 + comment-parser@1.4.6: {} + compare-func@2.0.0: dependencies: array-ify: 1.0.0 dot-prop: 5.3.0 - concat-map@0.0.1: {} - conventional-changelog-angular@8.3.1: dependencies: compare-func: 2.0.0 @@ -2486,149 +2172,23 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - data-view-buffer@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - debug@3.2.7: - dependencies: - ms: 2.1.3 - debug@4.4.3: dependencies: ms: 2.1.3 deep-is@0.1.4: {} - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - detect-libc@2.1.2: optional: true - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - dot-prop@5.3.0: dependencies: is-obj: 2.0.0 - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - electron-to-chromium@1.5.344: {} - es-abstract@1.24.2: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - call-bound: 1.0.4 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.3 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-negative-zero: 2.0.3 - is-regex: 1.2.1 - is-set: 2.0.3 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.4 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.20 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - es-module-lexer@2.0.0: {} - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.3 - - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.3 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - esbuild@0.27.7: optionalDependencies: '@esbuild/aix-ppc64': 0.27.7 @@ -2664,51 +2224,29 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-import-resolver-node@0.3.10: + eslint-import-context@0.1.9(unrs-resolver@1.11.1): dependencies: - debug: 3.2.7 - is-core-module: 2.16.1 - resolve: 2.0.0-next.6 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.59.0(eslint@10.2.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.2.1): - dependencies: - debug: 3.2.7 + get-tsconfig: 4.14.0 + stable-hash-x: 0.2.0 optionalDependencies: - '@typescript-eslint/parser': 8.59.0(eslint@10.2.1)(typescript@6.0.3) - eslint: 10.2.1 - eslint-import-resolver-node: 0.3.10 - transitivePeerDependencies: - - supports-color + unrs-resolver: 1.11.1 - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.0(eslint@10.2.1)(typescript@6.0.3))(eslint@10.2.1): + eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.59.0(eslint@10.2.1)(typescript@6.0.3))(eslint@10.2.1): dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 + '@package-json/types': 0.0.12 + '@typescript-eslint/types': 8.59.0 + comment-parser: 1.4.6 + debug: 4.4.3 eslint: 10.2.1 - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.59.0(eslint@10.2.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.2.1) - hasown: 2.0.3 - is-core-module: 2.16.1 + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) is-glob: 4.0.3 - minimatch: 3.1.5 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 + minimatch: 10.2.5 + semver: 7.7.4 + stable-hash-x: 0.2.0 + unrs-resolver: 1.11.1 optionalDependencies: - '@typescript-eslint/parser': 8.59.0(eslint@10.2.1)(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.0(eslint@10.2.1)(typescript@6.0.3) transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - supports-color eslint-plugin-unicorn@64.0.0(eslint@10.2.1): @@ -2833,53 +2371,14 @@ snapshots: flatted@3.4.2: {} - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - fsevents@2.3.3: optional: true - function-bind@1.1.2: {} - - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.3 - is-callable: 1.2.7 - - functions-have-names@1.2.3: {} - - generator-function@2.0.1: {} - generic-filehandle2@2.1.4: {} - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.3 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-symbol-description@1.1.0: + get-tsconfig@4.14.0: dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 + resolve-pkg-maps: 1.0.0 glob-parent@6.0.2: dependencies: @@ -2893,13 +2392,6 @@ snapshots: globals@17.5.0: {} - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - - gopd@1.2.0: {} - handlebars@4.7.9: dependencies: minimist: 1.2.8 @@ -2909,28 +2401,8 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 - has-bigints@1.1.0: {} - has-flag@4.0.0: {} - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-proto@1.2.0: - dependencies: - dunder-proto: 1.0.1 - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.3: - dependencies: - function-bind: 1.1.2 - hosted-git-info@8.1.0: dependencies: lru-cache: 10.4.3 @@ -2945,126 +2417,18 @@ snapshots: indent-string@5.0.0: {} - internal-slot@1.1.0: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.3 - side-channel: 1.1.0 - - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-async-function@2.1.1: - dependencies: - async-function: 1.0.0 - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-bigint@1.1.0: - dependencies: - has-bigints: 1.1.0 - - is-boolean-object@1.2.2: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - is-builtin-module@5.0.0: dependencies: builtin-modules: 5.1.0 - is-callable@1.2.7: {} - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.3 - - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-typed-array: 1.1.15 - - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - is-extglob@2.1.1: {} - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-generator-function@1.1.2: - dependencies: - call-bound: 1.0.4 - generator-function: 2.0.1 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - is-map@2.0.3: {} - - is-negative-zero@2.0.3: {} - - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - is-obj@2.0.0: {} - is-regex@1.2.1: - dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.3 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.4 - - is-string@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-symbol@1.1.1: - dependencies: - call-bound: 1.0.4 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.20 - - is-weakmap@2.0.2: {} - - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - isarray@2.0.5: {} - isexe@2.0.0: {} istanbul-lib-coverage@3.2.2: {} @@ -3090,10 +2454,6 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - json5@1.0.2: - dependencies: - minimist: 1.2.8 - keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -3175,18 +2535,12 @@ snapshots: dependencies: semver: 7.7.4 - math-intrinsics@1.1.0: {} - meow@13.2.0: {} minimatch@10.2.5: dependencies: brace-expansion: 5.0.5 - minimatch@3.1.5: - dependencies: - brace-expansion: 1.1.14 - minimist@1.2.8: {} minipass@7.1.3: {} @@ -3195,17 +2549,12 @@ snapshots: nanoid@3.3.11: {} + napi-postinstall@0.3.4: {} + natural-compare@1.4.0: {} neo-async@2.6.2: {} - node-exports-info@1.6.0: - dependencies: - array.prototype.flatmap: 1.3.3 - es-errors: 1.3.0 - object.entries: 1.1.9 - semver: 6.3.1 - node-releases@2.0.38: {} normalize-package-data@7.0.1: @@ -3214,46 +2563,6 @@ snapshots: semver: 7.7.4 validate-npm-package-license: 3.0.4 - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - object.entries@1.1.9: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-object-atoms: 1.1.1 - - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - obug@2.1.1: {} optionator@0.9.4: @@ -3265,12 +2574,6 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -3287,8 +2590,6 @@ snapshots: path-key@3.1.1: {} - path-parse@1.0.7: {} - path-scurry@2.0.2: dependencies: lru-cache: 11.3.5 @@ -3302,8 +2603,6 @@ snapshots: pluralize@8.0.0: {} - possible-typed-array-names@1.1.0: {} - postcss@8.5.10: dependencies: nanoid: 3.3.11 @@ -3316,40 +2615,13 @@ snapshots: punycode@2.3.1: {} - reflect.getprototypeof@1.0.10: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 - regexp-tree@0.1.27: {} - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 - regjsparser@0.13.1: dependencies: jsesc: 3.1.0 - resolve@2.0.0-next.6: - dependencies: - es-errors: 1.3.0 - is-core-module: 2.16.1 - node-exports-info: 1.6.0 - object-keys: 1.1.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 + resolve-pkg-maps@1.0.0: {} rimraf@6.1.3: dependencies: @@ -3387,85 +2659,14 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.60.2 fsevents: 2.3.3 - safe-array-concat@1.1.4: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - - semver@6.3.1: {} - semver@7.7.4: {} - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} - side-channel-list@1.0.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.1 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - siginfo@2.0.0: {} source-map-js@1.2.1: {} @@ -3486,6 +2687,8 @@ snapshots: spdx-license-ids@3.0.23: {} + stable-hash-x@0.2.0: {} + stackback@0.0.2: {} standard-changelog@7.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0): @@ -3500,44 +2703,12 @@ snapshots: std-env@4.1.0: {} - stop-iteration-iterator@1.1.0: - dependencies: - es-errors: 1.3.0 - internal-slot: 1.1.0 - - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - strip-bom@3.0.0: {} - strip-indent@4.1.1: {} supports-color@7.2.0: dependencies: has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - tinybench@2.9.0: {} tinyexec@1.1.1: {} @@ -3553,50 +2724,13 @@ snapshots: dependencies: typescript: 6.0.3 - tsconfig-paths@3.15.0: - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 + tslib@2.8.1: + optional: true type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.9 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - - typed-array-byte-offset@1.0.4: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 - - typed-array-length@1.0.7: - dependencies: - call-bind: 1.0.9 - for-each: 0.3.5 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 - reflect.getprototypeof: 1.0.10 - typescript-eslint@8.59.0(eslint@10.2.1)(typescript@6.0.3): dependencies: '@typescript-eslint/eslint-plugin': 8.59.0(@typescript-eslint/parser@8.59.0(eslint@10.2.1)(typescript@6.0.3))(eslint@10.2.1)(typescript@6.0.3) @@ -3613,15 +2747,32 @@ snapshots: uglify-js@3.19.3: optional: true - unbox-primitive@1.1.0: - dependencies: - call-bound: 1.0.4 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - undici-types@7.19.2: {} + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: browserslist: 4.28.2 @@ -3680,47 +2831,6 @@ snapshots: walk-up-path@4.0.0: {} - which-boxed-primitive@1.1.1: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - - which-builtin-type@1.2.1: - dependencies: - call-bound: 1.0.4 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.2 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.20 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - - which-typed-array@1.1.20: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - which@2.0.2: dependencies: isexe: 2.0.0 diff --git a/scripts/profile-ecoli.mjs b/scripts/profile-ecoli.mjs new file mode 100644 index 0000000..d265caf --- /dev/null +++ b/scripts/profile-ecoli.mjs @@ -0,0 +1,93 @@ +import { BamFile } from '../esm/index.js' + +async function time(label, fn, iterations) { + // warmup + for (let i = 0; i < 5; i++) { + await fn() + } + const start = performance.now() + for (let i = 0; i < iterations; i++) { + await fn() + } + const ms = performance.now() - start + console.log( + `${label}: ${iterations} iters, ${ms.toFixed(0)}ms total, ${(ms / iterations).toFixed(2)}ms/iter`, + ) + return ms +} + +const bamPath = 'test/data/ecoli_nanopore.bam' +const ref = 'ref000001|chr' + +// --- header/index parsing (what the benchmark actually measures) --- +await time( + 'header+index parse (new BamFile each time)', + async () => { + const bam = new BamFile({ bamPath }) + await bam.getHeader() + }, + 200, +) + +// --- single shared BamFile: record construction + filtering --- +{ + const bam = new BamFile({ bamPath }) + await bam.getHeader() + const records = await bam.getRecordsForRange(ref, 0, 5000000) + console.log(`\nrecords in region: ${records.length}`) + if (records[0]) { + const r = records[0] + console.log( + `sample: start=${r.start} end=${r.end} cigar_ops=${r.NUMERIC_CIGAR.length} seq_length=${r.seq_length}`, + ) + } + + await time( + 'getRecordsForRange (cached header)', + async () => { + await bam.getRecordsForRange(ref, 0, 5000000) + }, + 200, + ) + + // --- access properties that were hot in old vs new code --- + await time( + 'getRecordsForRange + end+NUMERIC_CIGAR (cached chunks)', + async () => { + const recs = await bam.getRecordsForRange(ref, 0, 5000000) + for (let i = 0; i < recs.length; i++) { + const r = recs[i] + void r.end + void r.NUMERIC_CIGAR + } + }, + 100, + ) + + // cold cache: clear between each iteration so records are re-parsed from raw bytes + await time( + 'getRecordsForRange + end+NUMERIC_CIGAR (cold cache)', + async () => { + bam.clearFeatureCache() + const recs = await bam.getRecordsForRange(ref, 0, 5000000) + for (let i = 0; i < recs.length; i++) { + const r = recs[i] + void r.end + void r.NUMERIC_CIGAR + } + }, + 100, + ) + + await time( + 'getRecordsForRange + end only (cold cache)', + async () => { + bam.clearFeatureCache() + const recs = await bam.getRecordsForRange(ref, 0, 5000000) + for (let i = 0; i < recs.length; i++) { + void recs[i].end + } + }, + 100, + ) +} diff --git a/src/bamFile.ts b/src/bamFile.ts index 79cb92f..43eab5a 100644 --- a/src/bamFile.ts +++ b/src/bamFile.ts @@ -35,6 +35,7 @@ export interface BamRecordLike { export type BamRecordClass = new (args: { bytes: Bytes fileOffset: number + dataView: DataView }) => T export const BAM_MAGIC = 21840194 @@ -501,6 +502,7 @@ export default class BamFile { chunk.minv.dataPosition + 1 : crc32(ba.subarray(blockStart, blockEnd)) >>> 0, + dataView, }) sink.push(feature) diff --git a/src/htsget.ts b/src/htsget.ts index 880a44b..381e387 100644 --- a/src/htsget.ts +++ b/src/htsget.ts @@ -1,11 +1,12 @@ import { unzip } from '@gmod/bgzf-filehandle' import BamFile, { BAM_MAGIC } from './bamFile.ts' +import Chunk from './chunk.ts' import { parseHeaderText } from './sam.ts' import { concatUint8Array } from './util.ts' +import { VirtualOffset } from './virtualOffset.ts' import type { BamRecordClass, BamRecordLike } from './bamFile.ts' -import type Chunk from './chunk.ts' import type BamRecord from './record.ts' import type { BamOpts, BaseOpts } from './util.ts' @@ -14,7 +15,7 @@ interface HtsgetChunk { headers?: Record } -async function concat(arr: HtsgetChunk[], opts?: Record) { +async function concat(arr: HtsgetChunk[], opts?: RequestInit) { const res = await Promise.all( arr.map(async chunk => { const { url, headers } = chunk @@ -29,12 +30,10 @@ async function concat(arr: HtsgetChunk[], opts?: Record) { return new Uint8Array(ret) } else { // remove referer header, it is not even allowed to be specified - // @ts-expect-error - - const { referer, ...rest } = headers + const { referer: _referer, ...rest } = headers ?? {} const res = await fetch(url, { ...opts, - headers: { ...opts?.headers, ...rest }, + headers: rest, }) if (!res.ok) { throw new Error( @@ -85,12 +84,17 @@ export default class HtsgetFile< ) } const data = await result.json() - const uncba = await concat(data.htsget.urls.slice(1), opts) - - const allRecords = await this.readBamFeatures(uncba, [], [], { - minv: { dataPosition: 0, blockPosition: 0 }, - maxv: { dataPosition: 0, blockPosition: 0 }, - } as Chunk) + const uncba = await concat(data.htsget.urls.slice(1), { + signal: opts?.signal, + }) + + const zero = new VirtualOffset(0, 0) + const allRecords = await this.readBamFeatures( + uncba, + [], + [], + new Chunk(zero, zero, 0), + ) const records: T[] = [] for (let i = 0, l = allRecords.length; i < l; i++) { @@ -115,7 +119,7 @@ export default class HtsgetFile< ) } const data = await result.json() - const uncba = await concat(data.htsget.urls, opts) + const uncba = await concat(data.htsget.urls, { signal: opts.signal }) const dataView = new DataView(uncba.buffer) if (dataView.getInt32(0, true) !== BAM_MAGIC) { @@ -123,7 +127,7 @@ export default class HtsgetFile< } const headLen = dataView.getInt32(4, true) - const decoder = new TextDecoder('utf8') + const decoder = new TextDecoder() const headerText = decoder.decode(uncba.subarray(8, 8 + headLen)) const samHeader = parseHeaderText(headerText) diff --git a/src/record.ts b/src/record.ts index 0a122b7..7d03559 100644 --- a/src/record.ts +++ b/src/record.ts @@ -17,6 +17,8 @@ const ASCII_CIGAR_CODES = [ 77, 73, 68, 78, 83, 72, 80, 61, 88, 63, 63, 63, 63, 63, 63, 63, ] +const textDecoder = new TextDecoder() + // Bitmask for ops that consume ref: M=0, D=2, N=3, P=6, ==7, X=8 // Binary: 0b111001101 = 0x1CD const CIGAR_CONSUMES_REF_MASK = 0x1cd @@ -27,55 +29,42 @@ export interface Bytes { byteArray: Uint8Array } -interface CIGAR_AND_LENGTH { - length_on_ref: number - NUMERIC_CIGAR: Uint32Array | number[] -} - export default class BamRecord { public fileOffset: number - private bytes: Bytes + private _byteArray: Uint8Array + private _start: number + private _end: number private _dataView: DataView - private _cachedFlags?: number - private _cachedRefId?: number - private _cachedStart?: number private _cachedEnd?: number private _cachedTags?: Record - private _cachedCigarAndLength?: CIGAR_AND_LENGTH + private _cachedLengthOnRef?: number + private _cachedNumericCigar?: Uint32Array | number[] private _cachedNUMERIC_MD?: Uint8Array | null private _cachedTagsStart?: number - constructor(args: { bytes: Bytes; fileOffset: number }) { - this.bytes = args.bytes + constructor(args: { bytes: Bytes; fileOffset: number; dataView: DataView }) { + this._byteArray = args.bytes.byteArray + this._start = args.bytes.start + this._end = args.bytes.end this.fileOffset = args.fileOffset - this._dataView = new DataView(this.bytes.byteArray.buffer) + this._dataView = args.dataView } get byteArray() { - return this.bytes.byteArray + return this._byteArray } get flags() { - if (this._cachedFlags === undefined) { - this._cachedFlags = - (this._dataView.getInt32(this.bytes.start + 16, true) & 0xffff0000) >> - 16 - } - return this._cachedFlags + return (this._dataView.getInt32(this._start + 16, true) & 0xffff0000) >> 16 } + get ref_id() { - if (this._cachedRefId === undefined) { - this._cachedRefId = this._dataView.getInt32(this.bytes.start + 4, true) - } - return this._cachedRefId + return this._dataView.getInt32(this._start + 4, true) } get start() { - if (this._cachedStart === undefined) { - this._cachedStart = this._dataView.getInt32(this.bytes.start + 8, true) - } - return this._cachedStart + return this._dataView.getInt32(this._start + 8, true) } get end() { @@ -98,12 +87,13 @@ export default class BamRecord { if (this.isSegmentUnmapped()) { return null } else { + const seqLen = this.seq_length const p = this.b0 + this.read_name_length + this.num_cigar_bytes + - this.num_seq_bytes - return this.byteArray.subarray(p, p + this.seq_length) + ((seqLen + 1) >> 1) + return this._byteArray.subarray(p, p + seqLen) } } @@ -112,25 +102,27 @@ export default class BamRecord { } get b0() { - return this.bytes.start + 36 + return this._start + 36 } get tagsStart() { if (this._cachedTagsStart === undefined) { + const seqLen = this.seq_length this._cachedTagsStart = this.b0 + this.read_name_length + this.num_cigar_bytes + - this.num_seq_bytes + - this.seq_length + ((seqLen + 1) >> 1) + + seqLen } return this._cachedTagsStart } + // batch fromCharCode: fastest for typical name lengths (see benchmarks/string-building.bench.ts) get name() { const len = this.read_name_length - 1 const start = this.b0 - const ba = this.byteArray + const ba = this._byteArray const codes = new Array(len) for (let i = 0; i < len; i++) { codes[i] = ba[start + i]! @@ -170,12 +162,12 @@ export default class BamRecord { let p = this.tagsStart - const blockEnd = this.bytes.end - const ba = this.byteArray + const blockEnd = this._end + const ba = this._byteArray while (p < blockEnd) { - const currentTag1 = ba[p]! - const currentTag2 = ba[p + 1]! - const type = ba[p + 2]! + const currentTag1 = ba[p] + const currentTag2 = ba[p + 1] + const type = ba[p + 2] p += 3 const isMatch = currentTag1 === tag1 && currentTag2 === tag2 @@ -232,26 +224,21 @@ export default class BamRecord { case 0x5a: // 'Z' case 0x48: { // 'H' + const start = p + while (p < blockEnd && ba[p] !== 0) { + p++ + } if (isMatch) { - const start = p - while (p < blockEnd && ba[p] !== 0) { - p++ - } - if (raw) { - return ba.subarray(start, p) - } - const value = [] - for (let i = start; i < p; i++) { - value.push(String.fromCharCode(ba[i]!)) - } - return value.join('') + return raw + ? ba.subarray(start, p) + : textDecoder.decode(ba.subarray(start, p)) } - while (p <= blockEnd && ba[p++] !== 0) {} + p++ // advance past null terminator break } case 0x42: { // 'B' - const Btype = ba[p++]! + const Btype = ba[p++] const limit = this._dataView.getInt32(p, true) p += 4 const absOffset = ba.byteOffset + p @@ -331,9 +318,9 @@ export default class BamRecord { private _computeTags() { let p = this.tagsStart - const blockEnd = this.bytes.end - const ba = this.byteArray - const tags = {} as Record + const blockEnd = this._end + const ba = this._byteArray + const tags: Record = {} while (p < blockEnd) { const tag = String.fromCharCode(ba[p]!, ba[p + 1]!) const type = ba[p + 2]! @@ -375,21 +362,17 @@ export default class BamRecord { case 0x5a: // 'Z' case 0x48: { // 'H' - const value = [] - while (p <= blockEnd) { - const cc = ba[p++]! - if (cc !== 0) { - value.push(String.fromCharCode(cc)) - } else { - break - } + const start = p + while (p < blockEnd && ba[p] !== 0) { + p++ } - tags[tag] = value.join('') + tags[tag] = textDecoder.decode(ba.subarray(start, p)) + p++ // advance past null terminator break } case 0x42: { // 'B' - const Btype = ba[p++]! + const Btype = ba[p++] const limit = this._dataView.getInt32(p, true) p += 4 const absOffset = ba.byteOffset + p @@ -520,13 +503,6 @@ export default class BamRecord { return !!(this.flags & Constants.BAM_FSUPPLEMENTARY) } - get cigarAndLength() { - if (this._cachedCigarAndLength === undefined) { - this._cachedCigarAndLength = this._computeCigarAndLength() - } - return this._cachedCigarAndLength - } - // Benchmark results for CIGAR parsing strategies (see benchmarks/cigar-lifecycle.bench.ts): // // Aligned data: @@ -545,78 +521,94 @@ export default class BamRecord { // // Strategy: use plain array with |0 for small aligned (≤50 ops) and all unaligned, // Uint32Array view only for large aligned CIGARs. - private _computeCigarAndLength() { - if (this.isSegmentUnmapped()) { - return { - length_on_ref: 0, - NUMERIC_CIGAR: new Uint32Array(0), - } + + // CG tag pattern: first op is soft-clip consuming entire sequence, second op is N encoding length-on-ref + private _isCGTagPattern(p: number) { + const cigop = this._dataView.getInt32(p, true) + return (cigop & 0xf) === CIGAR_SOFT_CLIP && cigop >> 4 === this.seq_length + } + + private _computeLengthOnRef(): number { + const flag_nc = this._dataView.getInt32(this._start + 16, true) + if (flag_nc & (Constants.BAM_FUNMAP << 16)) { + return 0 } - const numCigarOps = this.num_cigar_ops - let p = this.b0 + this.read_name_length + const numCigarOps = flag_nc & 0xffff + const p = this.b0 + this.read_name_length - // check for CG tag by inspecting whether the CIGAR field contains a clip - // that consumes entire seqLen - const cigop = this._dataView.getInt32(p, true) - const lop = cigop >> 4 - const op = cigop & 0xf - if (op === CIGAR_SOFT_CLIP && lop === this.seq_length) { - // if there is a CG the second CIGAR field will be a N tag the represents - // the length on ref - p += 4 - const cigop = this._dataView.getInt32(p, true) - const lop = cigop >> 4 - const op = cigop & 0xf - if (op !== CIGAR_REF_SKIP) { + if (this._isCGTagPattern(p)) { + const cigop2 = this._dataView.getInt32(p + 4, true) + if ((cigop2 & 0xf) !== CIGAR_REF_SKIP) { console.warn('CG tag with no N tag') } - const cgArray = this.tags.CG as Uint32Array - return { - NUMERIC_CIGAR: cgArray, - length_on_ref: lop, - } + return cigop2 >> 4 } - const absOffset = this.byteArray.byteOffset + p - const isAligned = absOffset % 4 === 0 - - if (isAligned && numCigarOps > 50) { + const absOffset = this._byteArray.byteOffset + p + if (absOffset % 4 === 0 && numCigarOps > 50) { const cigarView = new Uint32Array( - this.byteArray.buffer, + this._byteArray.buffer, absOffset, numCigarOps, ) + this._cachedNumericCigar = cigarView let lref = 0 for (let c = 0; c < numCigarOps; ++c) { - const cigop = cigarView[c]! - lref += (cigop >> 4) * ((CIGAR_CONSUMES_REF_MASK >> (cigop & 0xf)) & 1) - } - return { - NUMERIC_CIGAR: cigarView, - length_on_ref: lref, + const co = cigarView[c]! + lref += (co >> 4) * ((CIGAR_CONSUMES_REF_MASK >> (co & 0xf)) & 1) } + return lref } - const cigarArray: number[] = new Array(numCigarOps) let lref = 0 for (let c = 0; c < numCigarOps; ++c) { - const cigop = this._dataView.getInt32(p + c * 4, true) | 0 - cigarArray[c] = cigop - lref += (cigop >> 4) * ((CIGAR_CONSUMES_REF_MASK >> (cigop & 0xf)) & 1) + const co = this._dataView.getInt32(p + c * 4, true) + lref += (co >> 4) * ((CIGAR_CONSUMES_REF_MASK >> (co & 0xf)) & 1) } - return { - NUMERIC_CIGAR: cigarArray, - length_on_ref: lref, + return lref + } + + private _computeNumericCigar(): Uint32Array | number[] { + const flag_nc = this._dataView.getInt32(this._start + 16, true) + if (flag_nc & (Constants.BAM_FUNMAP << 16)) { + return new Uint32Array(0) } + + const numCigarOps = flag_nc & 0xffff + const p = this.b0 + this.read_name_length + + if (this._isCGTagPattern(p)) { + return ( + (this.tags.CG as Uint32Array | number[] | undefined) ?? + new Uint32Array(0) + ) + } + + const absOffset = this._byteArray.byteOffset + p + if (absOffset % 4 === 0 && numCigarOps > 50) { + return new Uint32Array(this._byteArray.buffer, absOffset, numCigarOps) + } + + const cigarArray: number[] = new Array(numCigarOps) + for (let c = 0; c < numCigarOps; ++c) { + cigarArray[c] = this._dataView.getInt32(p + c * 4, true) | 0 + } + return cigarArray } get length_on_ref() { - return this.cigarAndLength.length_on_ref + if (this._cachedLengthOnRef === undefined) { + this._cachedLengthOnRef = this._computeLengthOnRef() + } + return this._cachedLengthOnRef } get NUMERIC_CIGAR() { - return this.cigarAndLength.NUMERIC_CIGAR + if (this._cachedNumericCigar === undefined) { + this._cachedNumericCigar = this._computeNumericCigar() + } + return this._cachedNumericCigar } get CIGAR() { @@ -649,25 +641,26 @@ export default class BamRecord { get NUMERIC_SEQ() { const p = this.b0 + this.read_name_length + this.num_cigar_bytes - return this.byteArray.subarray(p, p + this.num_seq_bytes) + return this._byteArray.subarray(p, p + this.num_seq_bytes) } get seq() { - const numeric = this.NUMERIC_SEQ const len = this.seq_length + const seqStart = this.b0 + this.read_name_length + this.num_cigar_bytes + const numeric = this._byteArray const buf = new Array(len) let i = 0 const fullBytes = len >> 1 for (let j = 0; j < fullBytes; ++j) { - const sb = numeric[j]! - buf[i++] = SEQRET_DECODER[(sb & 0xf0) >> 4] - buf[i++] = SEQRET_DECODER[sb & 0x0f] + const sb = numeric[seqStart + j]! + buf[i++] = SEQRET_DECODER[(sb & 0xf0) >> 4]! + buf[i++] = SEQRET_DECODER[sb & 0x0f]! } if (i < len) { - const sb = numeric[fullBytes]! - buf[i] = SEQRET_DECODER[(sb & 0xf0) >> 4] + const sb = numeric[seqStart + fullBytes]! + buf[i] = SEQRET_DECODER[(sb & 0xf0) >> 4]! } return buf.join('') @@ -691,40 +684,40 @@ export default class BamRecord { } get bin_mq_nl() { - return this._dataView.getInt32(this.bytes.start + 12, true) + return this._dataView.getInt32(this._start + 12, true) } get flag_nc() { - return this._dataView.getInt32(this.bytes.start + 16, true) + return this._dataView.getInt32(this._start + 16, true) } get seq_length() { - return this._dataView.getInt32(this.bytes.start + 20, true) + return this._dataView.getInt32(this._start + 20, true) } get next_refid() { - return this._dataView.getInt32(this.bytes.start + 24, true) + return this._dataView.getInt32(this._start + 24, true) } get next_pos() { - return this._dataView.getInt32(this.bytes.start + 28, true) + return this._dataView.getInt32(this._start + 28, true) } get template_length() { - return this._dataView.getInt32(this.bytes.start + 32, true) + return this._dataView.getInt32(this._start + 32, true) } seqAt(idx: number): string | undefined { if (idx < this.seq_length) { const byteIndex = idx >> 1 const sb = - this.byteArray[ + this._byteArray[ this.b0 + this.read_name_length + this.num_cigar_bytes + byteIndex ]! return idx % 2 === 0 - ? SEQRET_DECODER[(sb & 0xf0) >> 4] - : SEQRET_DECODER[sb & 0x0f] + ? SEQRET_DECODER[(sb & 0xf0) >> 4]! + : SEQRET_DECODER[sb & 0x0f]! } else { return undefined } @@ -733,10 +726,10 @@ export default class BamRecord { toJSON() { const data: Record = {} for (const k of Object.keys(this)) { - if (k.startsWith('_') || k === 'bytes') { + if (k.startsWith('_')) { continue } - // @ts-ignore + // @ts-expect-error data[k] = this[k] } diff --git a/src/util.ts b/src/util.ts index 18f2162..abf3a82 100644 --- a/src/util.ts +++ b/src/util.ts @@ -34,7 +34,7 @@ export interface BaseOpts { } export function makeOpts(obj: AbortSignal | BaseOpts = {}): BaseOpts { - return 'aborted' in obj ? ({ signal: obj } as BaseOpts) : obj + return 'aborted' in obj ? { signal: obj } : obj } export function optimizeChunks(chunks: Chunk[], lowest?: Offset) { @@ -127,23 +127,22 @@ export function parseNameBytes( namesBytes: Uint8Array, renameRefSeq: (arg: string) => string = s => s, ) { + const decoder = new TextDecoder() let currRefId = 0 let currNameStart = 0 - const refIdToName = [] + const refIdToName: string[] = [] const refNameToId: Record = {} - for (let i = 0; i < namesBytes.length; i += 1) { + for (let i = 0; i < namesBytes.length; i++) { if (!namesBytes[i]) { if (currNameStart < i) { - let refName = '' - for (let j = currNameStart; j < i; j++) { - refName += String.fromCharCode(namesBytes[j]!) - } - refName = renameRefSeq(refName) + const refName = renameRefSeq( + decoder.decode(namesBytes.subarray(currNameStart, i)), + ) refIdToName[currRefId] = refName refNameToId[refName] = currRefId } currNameStart = i + 1 - currRefId += 1 + currRefId++ } } return { refNameToId, refIdToName } diff --git a/test/fakerecord.ts b/test/fakerecord.ts index 6a59dfd..9d38dac 100644 --- a/test/fakerecord.ts +++ b/test/fakerecord.ts @@ -15,17 +15,15 @@ export default class FakeRecord extends Record { tlen: number, { extraFlags = 0, refId = 1, nextRefId = 1 } = {}, ) { + const byteArray = Buffer.from(new Uint8Array(52)) super({ - bytes: { - start: 0, - end: 0, - byteArray: Buffer.from([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - ]), - }, + bytes: { start: 0, end: 0, byteArray }, fileOffset: 0, + dataView: new DataView( + byteArray.buffer, + byteArray.byteOffset, + byteArray.byteLength, + ), }) this.tlen = tlen this.nextrefid = nextRefId diff --git a/tsconfig.json b/tsconfig.json index a411d93..409b87c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,18 +4,17 @@ "target": "es2022", "module": "nodenext", "moduleResolution": "nodenext", - "lib": ["dom", "esnext"], + "lib": ["esnext", "dom"], "types": ["node"], "rootDir": "src", "outDir": "dist", "declaration": true, "sourceMap": true, "strict": true, - "noUncheckedIndexedAccess": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, "allowImportingTsExtensions": true, "rewriteRelativeImportExtensions": true, - "esModuleInterop": true + "esModuleInterop": true, + "skipLibCheck": true, + "noUncheckedIndexedAccess": true } }