diff --git a/packages/cubejs-backend-shared/package.json b/packages/cubejs-backend-shared/package.json index 2428ec7881f10..f599b3632a0c9 100644 --- a/packages/cubejs-backend-shared/package.json +++ b/packages/cubejs-backend-shared/package.json @@ -35,6 +35,7 @@ "typescript": "~5.2.2" }, "dependencies": { + "@node-rs/xxhash": "^1.7.6", "@oclif/color": "^0.1.2", "bytes": "^3.1.2", "cli-progress": "^3.9.0", diff --git a/packages/cubejs-backend-shared/src/promises.ts b/packages/cubejs-backend-shared/src/promises.ts index d458296060554..0c19f3927477e 100644 --- a/packages/cubejs-backend-shared/src/promises.ts +++ b/packages/cubejs-backend-shared/src/promises.ts @@ -1,6 +1,5 @@ /* eslint-disable arrow-body-style,no-restricted-syntax */ -import crypto from 'crypto'; - +import { xxh3 } from '@node-rs/xxhash'; import { Optional } from './type-helpers'; export type PromiseLock = { @@ -273,9 +272,7 @@ export const asyncDebounce = ( const cache = new Map>(); return async (...args: Arguments[]) => { - const key = crypto.createHash('md5') - .update(args.map((v) => JSON.stringify(v)).join(',')) - .digest('hex'); + const key = xxh3.xxh64(args.map((v) => JSON.stringify(v)).join(',')).toString(16); if (cache.has(key)) { return >cache.get(key); diff --git a/packages/cubejs-cubestore-driver/package.json b/packages/cubejs-cubestore-driver/package.json index 2897070080e55..eab401c8c813e 100644 --- a/packages/cubejs-cubestore-driver/package.json +++ b/packages/cubejs-cubestore-driver/package.json @@ -30,6 +30,7 @@ "@cubejs-backend/cubestore": "1.2.30", "@cubejs-backend/native": "1.2.30", "@cubejs-backend/shared": "1.2.30", + "@node-rs/xxhash": "^1.7.6", "csv-write-stream": "^2.0.0", "flatbuffers": "23.3.3", "fs-extra": "^9.1.0", diff --git a/packages/cubejs-cubestore-driver/src/CubeStoreQueueDriver.ts b/packages/cubejs-cubestore-driver/src/CubeStoreQueueDriver.ts index bdbb1f33872fe..19958fcf88776 100644 --- a/packages/cubejs-cubestore-driver/src/CubeStoreQueueDriver.ts +++ b/packages/cubejs-cubestore-driver/src/CubeStoreQueueDriver.ts @@ -1,4 +1,4 @@ -import crypto from 'crypto'; +import { xxh3 } from '@node-rs/xxhash'; import { QueueDriverInterface, QueueDriverConnectionInterface, @@ -22,7 +22,7 @@ import { CubeStoreDriver } from './CubeStoreDriver'; function hashQueryKey(queryKey: QueryKey, processUid?: string): QueryKeyHash { processUid = processUid || getProcessUid(); - const hash = crypto.createHash('md5').update(JSON.stringify(queryKey)).digest('hex'); + const hash = xxh3.xxh128(JSON.stringify(queryKey)).toString(16); if (typeof queryKey === 'object' && queryKey.persistent) { return `${hash}@${processUid}` as any; @@ -83,7 +83,7 @@ class CubestoreQueueDriverConnection implements QueueDriverConnectionInterface { values.push(JSON.stringify(data)); const rows = await this.driver.query(`QUEUE ADD PRIORITY ?${options.orphanedTimeout ? ' ORPHANED ?' : ''} ? ?`, values); - if (rows && rows.length) { + if (rows?.length) { return [ rows[0].added === 'true' ? 1 : 0, rows[0].id ? parseInt(rows[0].id, 10) : null, @@ -104,7 +104,7 @@ class CubestoreQueueDriverConnection implements QueueDriverConnectionInterface { // queryKeyHash as compatibility fallback queueId || this.prefixKey(hash), ]); - if (rows && rows.length) { + if (rows?.length) { return this.decodeQueryDefFromRow(rows[0], 'cancelQuery'); } @@ -149,7 +149,7 @@ class CubestoreQueueDriverConnection implements QueueDriverConnectionInterface { const rows = await this.driver.query('CACHE INCR ?', [ `${this.options.redisQueuePrefix}:PROCESSING_COUNTER` ]); - if (rows && rows.length) { + if (rows?.length) { return rows[0].value; } @@ -186,7 +186,7 @@ class CubestoreQueueDriverConnection implements QueueDriverConnectionInterface { const rows = await this.driver.query('QUEUE RESULT ?', [ this.prefixKey(this.redisHash(queryKey)), ]); - if (rows && rows.length) { + if (rows?.length) { return this.decodeQueryDefFromRow(rows[0], 'getResult'); } @@ -245,7 +245,7 @@ class CubestoreQueueDriverConnection implements QueueDriverConnectionInterface { const rows = await this.driver.query('QUEUE GET ?', [ queueId || this.prefixKey(hash), ]); - if (rows && rows.length) { + if (rows?.length) { return this.decodeQueryDefFromRow(rows[0], 'getQueryDef'); } @@ -271,7 +271,7 @@ class CubestoreQueueDriverConnection implements QueueDriverConnectionInterface { this.options.concurrency, this.prefixKey(hash), ]); - if (rows && rows.length) { + if (rows?.length) { const active = rows[0].active ? (rows[0].active).split(',') as unknown as QueryKeyHash[] : []; const pending = parseInt(rows[0].pending, 10); @@ -302,7 +302,7 @@ class CubestoreQueueDriverConnection implements QueueDriverConnectionInterface { // queryKeyHash as compatibility fallback queueId || this.prefixKey(hash), ]); - if (rows && rows.length) { + if (rows?.length) { return this.decodeQueryDefFromRow(rows[0], 'getResultBlocking'); } @@ -348,8 +348,8 @@ export class CubeStoreQueueDriver implements QueueDriverInterface { return this.connection; } - // eslint-disable-next-line no-return-assign - return this.connection = await this.driverFactory(); + this.connection = await this.driverFactory(); + return this.connection; } public async createConnection(): Promise { diff --git a/packages/cubejs-query-orchestrator/package.json b/packages/cubejs-query-orchestrator/package.json index 619c92b1b4392..49751bc9d0e0a 100644 --- a/packages/cubejs-query-orchestrator/package.json +++ b/packages/cubejs-query-orchestrator/package.json @@ -32,6 +32,7 @@ "@cubejs-backend/base-driver": "1.2.30", "@cubejs-backend/cubestore-driver": "1.2.30", "@cubejs-backend/shared": "1.2.30", + "@node-rs/xxhash": "^1.7.6", "csv-write-stream": "^2.0.0", "generic-pool": "^3.8.2", "lru-cache": "^5.1.1", diff --git a/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregations.ts b/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregations.ts index f15cc56ab286f..1ccd687d3adf4 100644 --- a/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregations.ts +++ b/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregations.ts @@ -29,6 +29,7 @@ export function version(cacheKey) { let result = ''; const hashCharset = 'abcdefghijklmnopqrstuvwxyz012345'; + // TODO: switch to use '@node-rs/xxhash' instead of crypto const digestBuffer = crypto.createHash('md5').update(JSON.stringify(cacheKey)).digest(); let residue = 0; diff --git a/packages/cubejs-query-orchestrator/src/orchestrator/utils.ts b/packages/cubejs-query-orchestrator/src/orchestrator/utils.ts index 1e9c366a09a61..b16a1b9afa784 100644 --- a/packages/cubejs-query-orchestrator/src/orchestrator/utils.ts +++ b/packages/cubejs-query-orchestrator/src/orchestrator/utils.ts @@ -1,4 +1,4 @@ -import crypto from 'crypto'; +import { xxh3 } from '@node-rs/xxhash'; import { getProcessUid } from '@cubejs-backend/shared'; import { QueryKey, QueryKeyHash } from '@cubejs-backend/base-driver'; @@ -18,16 +18,11 @@ export function getCacheHash(queryKey: QueryKey | CacheKey, processUid?: string) return queryKey as any; } + const hash = xxh3.xxh128(JSON.stringify(queryKey)).toString(16); + if (typeof queryKey === 'object' && 'persistent' in queryKey && queryKey.persistent) { - return `${crypto - .createHash('md5') - .update(JSON.stringify(queryKey)) - .digest('hex') - }@${processUid}` as any; + return `${hash}@${processUid}` as any; } else { - return crypto - .createHash('md5') - .update(JSON.stringify(queryKey)) - .digest('hex') as any; + return hash as any; } } diff --git a/packages/cubejs-query-orchestrator/test/unit/QueryQueue.abstract.ts b/packages/cubejs-query-orchestrator/test/unit/QueryQueue.abstract.ts index 57466ce9034d4..e915d32f42b89 100644 --- a/packages/cubejs-query-orchestrator/test/unit/QueryQueue.abstract.ts +++ b/packages/cubejs-query-orchestrator/test/unit/QueryQueue.abstract.ts @@ -323,7 +323,7 @@ export const QueryQueueTest = (name: string, options: QueryQueueTestOptions = {} expect(processUidRE.test(key3.split('@')[1])).toBeTruthy(); if (options.cacheAndQueueDriver === 'cubestore') { - expect(queue.redisHash('string')).toBe('095d71cf12556b9d5e330ad575b3df5d'); + expect(queue.redisHash('string')).toBe('7aeaa28c6474df82129b9fe0d65c3ae4'); } else { expect(queue.redisHash('string')).toBe('string'); } diff --git a/packages/cubejs-server-core/package.json b/packages/cubejs-server-core/package.json index f2eb42b057db9..bca8ece2e42ac 100644 --- a/packages/cubejs-server-core/package.json +++ b/packages/cubejs-server-core/package.json @@ -37,6 +37,7 @@ "@cubejs-backend/schema-compiler": "1.2.30", "@cubejs-backend/shared": "1.2.30", "@cubejs-backend/templates": "1.2.30", + "@node-rs/xxhash": "^1.7.6", "codesandbox-import-utils": "^2.1.12", "cross-spawn": "^7.0.1", "fs-extra": "^8.1.0", diff --git a/packages/cubejs-server-core/src/core/CompilerApi.js b/packages/cubejs-server-core/src/core/CompilerApi.js index 71c5517e5976e..f40ce63d3da76 100644 --- a/packages/cubejs-server-core/src/core/CompilerApi.js +++ b/packages/cubejs-server-core/src/core/CompilerApi.js @@ -1,4 +1,4 @@ -import crypto from 'crypto'; +import { xxh3 } from '@node-rs/xxhash'; import R from 'ramda'; import { createQuery, compile, queryClass, PreAggregations, QueryFactory } from '@cubejs-backend/schema-compiler'; import { v4 as uuidv4, parse as uuidParse, stringify as uuidStringify } from 'uuid'; @@ -55,7 +55,7 @@ export class CompilerApi { if (this.options.devServer || this.options.fastReload) { const files = await this.repository.dataSchemaFiles(); - compilerVersion += `_${crypto.createHash('md5').update(JSON.stringify(files)).digest('hex')}`; + compilerVersion += `_${xxh3.xxh64(JSON.stringify(files)).toString(16)}`; } if (!this.compilers || this.compilerVersion !== compilerVersion) { @@ -224,7 +224,7 @@ export class CompilerApi { hashRequestContext(context) { if (!context.__hash) { - context.__hash = crypto.createHash('md5').update(JSON.stringify(context)).digest('hex'); + context.__hash = xxh3.xxh64(JSON.stringify(context)).toString(16); } return context.__hash; } @@ -505,7 +505,7 @@ export class CompilerApi { const visibiliyMask = JSON.stringify(isMemberVisibleInContext, Object.keys(isMemberVisibleInContext).sort()); // This hash will be returned along the modified meta config and can be used // to distinguish between different "schema versions" after DAP visibility is applied - const visibilityMaskHash = crypto.createHash('sha256').update(visibiliyMask).digest('hex'); + const visibilityMaskHash = xxh3.xxh64(visibiliyMask).toString(16); return { cubes: cubes @@ -523,10 +523,7 @@ export class CompilerApi { } mixInVisibilityMaskHash(compilerId, visibilityMaskHash) { - const uuidBytes = uuidParse(compilerId); - const hashBytes = Buffer.from(visibilityMaskHash, 'hex'); - return uuidv4({ random: crypto.createHash('sha256').update(uuidBytes).update(hashBytes).digest() - .subarray(0, 16) }); + return uuidv4({ random: Buffer.from(xxh3.xxh64(`${compilerId}${visibilityMaskHash}`).toString()) }); } async metaConfig(requestContext, options = {}) { @@ -542,8 +539,8 @@ export class CompilerApi { return { cubes: patchedCubes, // This compilerId is primarily used by the cubejs-backend-native or caching purposes. - // By default it doesn't account for member visibility changes introduced above by DAP. - // Here we're modifying the originila compilerId in a way that it's distinct for + // By default, it doesn't account for member visibility changes introduced above by DAP. + // Here we're modifying the original compilerId in a way that it's distinct for // distinct schema versions while still being a valid UUID. compilerId: visibilityMaskHash ? this.mixInVisibilityMaskHash(compilers.compilerId, visibilityMaskHash) : compilers.compilerId, }; diff --git a/packages/cubejs-server-core/src/core/RefreshScheduler.ts b/packages/cubejs-server-core/src/core/RefreshScheduler.ts index 777ed886899a4..6198eaa3515ac 100644 --- a/packages/cubejs-server-core/src/core/RefreshScheduler.ts +++ b/packages/cubejs-server-core/src/core/RefreshScheduler.ts @@ -1,7 +1,7 @@ import R from 'ramda'; import pLimit from 'p-limit'; import { v4 as uuidv4 } from 'uuid'; -import crypto from 'crypto'; +import { xxh3 } from '@node-rs/xxhash'; import { Required } from '@cubejs-backend/shared'; import { PreAggregationDescription, @@ -127,10 +127,7 @@ function getPreAggsJobsList( * Returns MD5 hash token of the job object. */ function getPreAggJobToken(job: PreAggJob) { - return crypto - .createHash('md5') - .update(JSON.stringify(job)) - .digest('hex'); + return xxh3.xxh64(JSON.stringify(job)).toString(16); } export class RefreshScheduler { diff --git a/packages/cubejs-testing/test/smoke-cubesql.test.ts b/packages/cubejs-testing/test/smoke-cubesql.test.ts index e8d71956921e4..e4f40277ac49a 100644 --- a/packages/cubejs-testing/test/smoke-cubesql.test.ts +++ b/packages/cubejs-testing/test/smoke-cubesql.test.ts @@ -179,23 +179,23 @@ describe('SQL API', () => { } it('regular query', async () => { - expect(await generateSql(`SELECT SUM(totalAmount) AS total FROM Orders;`)).toMatchSnapshot(); + expect(await generateSql('SELECT SUM(totalAmount) AS total FROM Orders;')).toMatchSnapshot(); }); it('regular query with missing column', async () => { - expect(await generateSql(`SELECT SUM(foobar) AS total FROM Orders;`)).toMatchSnapshot(); + expect(await generateSql('SELECT SUM(foobar) AS total FROM Orders;')).toMatchSnapshot(); }); it('regular query with parameters', async () => { - expect(await generateSql(`SELECT SUM(totalAmount) AS total FROM Orders WHERE status = 'foo';`)).toMatchSnapshot(); + expect(await generateSql('SELECT SUM(totalAmount) AS total FROM Orders WHERE status = \'foo\';')).toMatchSnapshot(); }); it('strictly post-processing', async () => { - expect(await generateSql(`SELECT version();`)).toMatchSnapshot(); + expect(await generateSql('SELECT version();')).toMatchSnapshot(); }); it('strictly post-processing with disabled post-processing', async () => { - expect(await generateSql(`SELECT version();`, true)).toMatchSnapshot(); + expect(await generateSql('SELECT version();', true)).toMatchSnapshot(); }); it('double aggregation post-processing', async () => { diff --git a/packages/cubejs-testing/test/smoke-duckdb.test.ts b/packages/cubejs-testing/test/smoke-duckdb.test.ts index 7da0e57b4a3b8..55c7266ec6a4d 100644 --- a/packages/cubejs-testing/test/smoke-duckdb.test.ts +++ b/packages/cubejs-testing/test/smoke-duckdb.test.ts @@ -90,7 +90,7 @@ describe('duckdb', () => { ] }); - // There are 2 'processed' orders + // There are 2 'processed' orders expect(response.rawData()[0]['Orders.count']).toBe('2'); }); diff --git a/yarn.lock b/yarn.lock index fc962405e7d51..6fcccd246c9cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5241,7 +5241,7 @@ pump "^3.0.0" secure-json-parse "^2.3.1" -"@emnapi/core@^1.1.0": +"@emnapi/core@^1.1.0", "@emnapi/core@^1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.3.1.tgz#9c62d185372d1bddc94682b87f376e03dfac3f16" integrity sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog== @@ -5249,7 +5249,7 @@ "@emnapi/wasi-threads" "1.0.1" tslib "^2.4.0" -"@emnapi/runtime@^1.1.0": +"@emnapi/runtime@^1.1.0", "@emnapi/runtime@^1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60" integrity sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw== @@ -6492,6 +6492,15 @@ "@emnapi/runtime" "^1.1.0" "@tybys/wasm-util" "^0.9.0" +"@napi-rs/wasm-runtime@^0.2.5": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.7.tgz#288f03812a408bc53c2c3686c65f38fe90f295eb" + integrity sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw== + dependencies: + "@emnapi/core" "^1.3.1" + "@emnapi/runtime" "^1.3.1" + "@tybys/wasm-util" "^0.9.0" + "@ngtools/webpack@13.3.11": version "13.3.11" resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-13.3.11.tgz#3295a7ae2b93f2cc5e197b72efb0f5b9c63c4685" @@ -6504,6 +6513,98 @@ dependencies: easy-stack "1.0.1" +"@node-rs/xxhash-android-arm-eabi@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-android-arm-eabi/-/xxhash-android-arm-eabi-1.7.6.tgz#49c9461e73f7bbd30d1c3fba289f5abd70b2642e" + integrity sha512-ptmfpFZ8SgTef58Us+0HsZ9BKhyX/gZYbhLkuzPt7qUoMqMSJK85NC7LEgzDgjUiG+S5GahEEQ9/tfh9BVvKhw== + +"@node-rs/xxhash-android-arm64@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-android-arm64/-/xxhash-android-arm64-1.7.6.tgz#ddf69837c66b1531590a6cb0b065570946c993e2" + integrity sha512-n4MyZvqifuoARfBvrZ2IBqmsGzwlVI3kb2mB0gVvoHtMsPbl/q94zoDBZ7WgeP3t4Wtli+QS3zgeTCOWUbqqUQ== + +"@node-rs/xxhash-darwin-arm64@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-darwin-arm64/-/xxhash-darwin-arm64-1.7.6.tgz#768b73984b7239dff40e1df35d412e39b7cd3a2e" + integrity sha512-6xGuE07CiCIry/KT3IiwQd/kykTOmjKzO/ZnHlE5ibGMx64NFE0qDuwJbxQ4rGyUzgJ0KuN9ZdOhUDJmepnpcw== + +"@node-rs/xxhash-darwin-x64@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-darwin-x64/-/xxhash-darwin-x64-1.7.6.tgz#b22fd63c9b337d3c6ff5acd2b26a9bb6e53285af" + integrity sha512-Z4oNnhyznDvHhxv+s0ka+5KG8mdfLVucZMZMejj9BL+CPmamClygPiHIRiifRcPAoX9uPZykaCsULngIfLeF3Q== + +"@node-rs/xxhash-freebsd-x64@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-freebsd-x64/-/xxhash-freebsd-x64-1.7.6.tgz#16fd0350fbed351bcdaf0d7f22ceee9579eb93a6" + integrity sha512-arCDOf3xZ5NfBL5fk5J52sNPjXL2cVWN6nXNB3nrtRFFdPBLsr6YXtshAc6wMVxnIW4VGaEv/5K6IpTA8AFyWw== + +"@node-rs/xxhash-linux-arm-gnueabihf@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-arm-gnueabihf/-/xxhash-linux-arm-gnueabihf-1.7.6.tgz#fa89aa1e69b872d858c42e91b380eed7440ec21a" + integrity sha512-ndLLEW+MwLH3lFS0ahlHCcmkf2ykOv/pbP8OBBeAOlz/Xc3jKztg5IJ9HpkjKOkHk470yYxgHVaw1QMoMzU00A== + +"@node-rs/xxhash-linux-arm64-gnu@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-arm64-gnu/-/xxhash-linux-arm64-gnu-1.7.6.tgz#b39d340779fcca5240da1c78a70504341b6abfa4" + integrity sha512-VX7VkTG87mAdrF2vw4aroiRpFIIN8Lj6NgtGHF+IUVbzQxPudl4kG+FPEjsNH8y04yQxRbPE7naQNgHcTKMrNw== + +"@node-rs/xxhash-linux-arm64-musl@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-arm64-musl/-/xxhash-linux-arm64-musl-1.7.6.tgz#3adfa6a0793617a32dc8208f2eb542a095af01d2" + integrity sha512-AB5m6crGYSllM9F/xZNOQSPImotR5lOa9e4arW99Bv82S+gcpphI8fGMDOVTTCXY/RLRhvvhwzLDxmLB2O8VDg== + +"@node-rs/xxhash-linux-x64-gnu@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-x64-gnu/-/xxhash-linux-x64-gnu-1.7.6.tgz#b82e8bd2b8c38ed10044e531741e2684806c071e" + integrity sha512-a2A6M+5tc0PVlJlE/nl0XsLEzMpKkwg7Y1lR5urFUbW9uVQnKjJYQDrUojhlXk0Uv3VnYQPa6ThmwlacZA5mvQ== + +"@node-rs/xxhash-linux-x64-musl@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-linux-x64-musl/-/xxhash-linux-x64-musl-1.7.6.tgz#b23bbc32837693c0e7c1d2b5bb6d84c1a0987d0f" + integrity sha512-WioGJSC1GoxQpmdQrG5l/uddSBAS4XCWczHNwXe895J5xadGQzyvmr0r17BNfihvbBUDH1H9jwouNYzDDeA6+A== + +"@node-rs/xxhash-wasm32-wasi@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-wasm32-wasi/-/xxhash-wasm32-wasi-1.7.6.tgz#ca5ae8b2c1a65dcbb349713685ddf0479bb01e7e" + integrity sha512-WDXXKMMFMrez+esm2DzMPHFNPFYf+wQUtaXrXwtxXeQMFEzleOLwEaqV0+bbXGJTwhPouL3zY1Qo2xmIH4kkTg== + dependencies: + "@napi-rs/wasm-runtime" "^0.2.5" + +"@node-rs/xxhash-win32-arm64-msvc@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-win32-arm64-msvc/-/xxhash-win32-arm64-msvc-1.7.6.tgz#b6b6fd422ab4af6411fb00c05a49fe5185387868" + integrity sha512-qjDFUZJT/Zq0yFS+0TApkD86p0NBdPXlOoHur9yNeO9YX2/9/b1sC2P7N27PgOu13h61TUOvTUC00e/82jAZRQ== + +"@node-rs/xxhash-win32-ia32-msvc@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-win32-ia32-msvc/-/xxhash-win32-ia32-msvc-1.7.6.tgz#512671309ef5b7aa5e675f58a167e99ff968bceb" + integrity sha512-s7a+mQWOTnU4NiiypRq/vbNGot/il0HheXuy9oxJ0SW2q/e4BJ8j0pnP6UBlAjsk+005A76vOwsEj01qbQw8+A== + +"@node-rs/xxhash-win32-x64-msvc@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash-win32-x64-msvc/-/xxhash-win32-x64-msvc-1.7.6.tgz#3ac70d92d85028999bdda209cd587871e077bb78" + integrity sha512-zHOHm2UaIahRhgRPJll+4Xy4Z18aAT/7KNeQW+QJupGvFz+GzOFXMGs3R/3B1Ktob/F5ui3i1MrW9GEob3CWTg== + +"@node-rs/xxhash@^1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@node-rs/xxhash/-/xxhash-1.7.6.tgz#8ba2c17a3d0ea2cd2ea4db2568bb357a82ea9ca4" + integrity sha512-XMisO+aQHsVpxRp/85EszTtOQTOlhPbd149P/Xa9F55wafA6UM3h2UhOgOs7aAzItnHU/Aw1WQ1FVTEg7WB43Q== + optionalDependencies: + "@node-rs/xxhash-android-arm-eabi" "1.7.6" + "@node-rs/xxhash-android-arm64" "1.7.6" + "@node-rs/xxhash-darwin-arm64" "1.7.6" + "@node-rs/xxhash-darwin-x64" "1.7.6" + "@node-rs/xxhash-freebsd-x64" "1.7.6" + "@node-rs/xxhash-linux-arm-gnueabihf" "1.7.6" + "@node-rs/xxhash-linux-arm64-gnu" "1.7.6" + "@node-rs/xxhash-linux-arm64-musl" "1.7.6" + "@node-rs/xxhash-linux-x64-gnu" "1.7.6" + "@node-rs/xxhash-linux-x64-musl" "1.7.6" + "@node-rs/xxhash-wasm32-wasi" "1.7.6" + "@node-rs/xxhash-win32-arm64-msvc" "1.7.6" + "@node-rs/xxhash-win32-ia32-msvc" "1.7.6" + "@node-rs/xxhash-win32-x64-msvc" "1.7.6" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"