diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8424910..20ba2e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: submodules: recursive - uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 22.12 cache: npm - run: npm ci - run: node --test scripts/*.node-test.js @@ -57,7 +57,7 @@ jobs: submodules: recursive - uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 22.12 cache: npm - uses: dtolnay/rust-toolchain@stable with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8816efc..fcec851 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 22.12 cache: npm - name: Verify tagged release version if: github.event_name == 'push' || inputs.publish_release diff --git a/package-lock.json b/package-lock.json index e155cdc..3a13fe2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,10 +41,10 @@ "tailwindcss": "^4.3.3", "typescript": "^7.0.2", "vite": "^8.2.2", - "vitest": "^4.1.11" + "vitest": "^5.0.0" }, "engines": { - "node": ">=22" + "node": ">=22.12" } }, "node_modules/@babel/runtime": { @@ -418,13 +418,6 @@ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", "license": "MIT" }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "dev": true, - "license": "MIT" - }, "node_modules/@tailwindcss/node": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", @@ -1445,34 +1438,17 @@ } } }, - "node_modules/@vitest/expect": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", - "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@standard-schema/spec": "^1.1.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", - "chai": "^6.2.2", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/@vitest/mocker": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", - "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.0.tgz", + "integrity": "sha512-66PGTMIiVJP3t4a5yxU9qPtf7MdTBs8jmToMvy+HVflB3Yy13WJZTtPePdvU+wjRV02SKK5doLbSA6o9pwOmiA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.11", + "@jridgewell/trace-mapping": "0.3.31", + "@vitest/spy": "5.0.0", "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" + "magic-string": "^1.2.3" }, "funding": { "url": "https://opencollective.com/vitest" @@ -1490,74 +1466,26 @@ } } }, - "node_modules/@vitest/pretty-format": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", - "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", + "node_modules/@vitest/mocker/node_modules/magic-string": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.2.3.tgz", + "integrity": "sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", - "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "4.1.11", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", - "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.11", - "@vitest/utils": "4.1.11", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/@vitest/spy": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", - "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.0.tgz", + "integrity": "sha512-uy+luWBAPw9XfthoHi5AkfHUnuPYEESjl0p/r+meoBnU8bxg5GDQ3Ey8MjcJ6sqahkL4PFyrvfMJJBw7LbU06g==", "dev": true, "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/utils": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", - "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.11", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -1683,13 +1611,6 @@ "node": ">=18" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -1727,9 +1648,9 @@ } }, "node_modules/es-module-lexer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", - "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", "dev": true, "license": "MIT" }, @@ -2181,13 +2102,6 @@ "node": ">=12.20.0" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -2195,9 +2109,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -2377,11 +2291,14 @@ } }, "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.1.4.tgz", + "integrity": "sha512-9APumHG7r4yOk4X4WlkmE71aZcv1gvin1czO3OQ1U9iJcFA5Ja/ygyb0vPOVHTthFozUYs8CLoLUlM8grb2lTQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } }, "node_modules/tinyexec": { "version": "1.3.0", @@ -2409,16 +2326,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyrainbow": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", - "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/typescript": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", @@ -2833,38 +2740,31 @@ } }, "node_modules/vitest": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", - "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.0.tgz", + "integrity": "sha512-gpsMNoRhMjMktVxPtstOH4/PJuPyovVaMDr4oDilXaGH1EcqM2OE96SoHT2VIQ6fTGtTjqmHDrEu2X9RQiXf8Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.11", - "@vitest/mocker": "4.1.11", - "@vitest/pretty-format": "4.1.11", - "@vitest/runner": "4.1.11", - "@vitest/snapshot": "4.1.11", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", - "es-module-lexer": "^2.0.0", - "expect-type": "^1.3.0", - "magic-string": "^0.30.21", - "obug": "^2.1.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "std-env": "^4.0.0-rc.1", - "tinybench": "^2.9.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.1.0", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "@types/chai": "^5.2.2", + "@vitest/mocker": "5.0.0", + "chai": "^6.2.2", + "es-module-lexer": "^2.3.2", + "expect-type": "^1.4.0", + "magic-string": "^1.2.3", + "obug": "^2.1.4", + "picomatch": "^4.0.7", + "std-env": "^4.2.0", + "tinybench": "6.1.4", + "tinyexec": "1.3.0", + "tinyglobby": "^0.2.17", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^22.12.0 || ^24.0.0 || >=26.0.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -2872,16 +2772,16 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", - "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.11", - "@vitest/browser-preview": "4.1.11", - "@vitest/browser-webdriverio": "4.1.11", - "@vitest/coverage-istanbul": "4.1.11", - "@vitest/coverage-v8": "4.1.11", - "@vitest/ui": "4.1.11", + "@types/node": "^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "5.0.0", + "@vitest/browser-preview": "5.0.0", + "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", + "@vitest/coverage-istanbul": "5.0.0", + "@vitest/coverage-v8": "5.0.0", + "@vitest/ui": "5.0.0", "happy-dom": "*", "jsdom": "*", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { @@ -2922,6 +2822,16 @@ } } }, + "node_modules/vitest/node_modules/magic-string": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.2.3.tgz", + "integrity": "sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", diff --git a/package.json b/package.json index 2170fe3..1c800c7 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "desktop" ], "engines": { - "node": ">=22" + "node": ">=22.12" }, "type": "module", "scripts": { @@ -41,7 +41,8 @@ "verify:macos-signing": "node scripts/verify-macos-signing.js", "preview": "vite preview", "tauri": "node scripts/tauri-command.js", - "test": "vitest" + "test": "vitest", + "test:race": "vitest run --repeats 5 src/utils/dockBadge.test.ts src/store/downloadStore.test.ts src/store/useDownloadStore.test.ts" }, "dependencies": { "@fontsource-variable/inter": "^5.3.0", @@ -76,6 +77,6 @@ "tailwindcss": "^4.3.3", "typescript": "^7.0.2", "vite": "^8.2.2", - "vitest": "^4.1.11" + "vitest": "^5.0.0" } } diff --git a/src/store/useDownloadStore.test.ts b/src/store/useDownloadStore.test.ts index c272dcd..4c21a61 100644 --- a/src/store/useDownloadStore.test.ts +++ b/src/store/useDownloadStore.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { commitDownloadState, dispatchItem, flushDownloadPersistence, getProxyArgs, getSiteLogin, hasStaleTemporaryMediaEstimate, initializeDownloadPersistence, MAIN_QUEUE_ID, normalizeCustomProxy, normalizePersistedDownloadProgress, normalizePersistedQueueState, normalizePersistedQueues, useDownloadStore } from './useDownloadStore'; +import { commitDownloadState, currentDownloadLifecycleGeneration, dispatchItem, flushDownloadPersistence, getProxyArgs, getSiteLogin, hasStaleTemporaryMediaEstimate, initializeDownloadPersistence, MAIN_QUEUE_ID, normalizeCustomProxy, normalizePersistedDownloadProgress, normalizePersistedQueueState, normalizePersistedQueues, resetDownloadStoreModuleStateForTests, useDownloadStore } from './useDownloadStore'; import { useDownloadProgressStore } from './downloadProgressStore'; import { useSettingsStore } from './useSettingsStore'; import * as ipc from '../ipc'; @@ -61,6 +61,7 @@ vi.mock('./useSettingsStore', () => ({ describe('useDownloadStore', () => { beforeEach(() => { + resetDownloadStoreModuleStateForTests(); vi.clearAllMocks(); vi.mocked(useSettingsStore.getState).mockReturnValue({ proxyMode: 'none', @@ -1409,6 +1410,7 @@ describe('useDownloadStore', () => { }); it('does not resurrect a row removed while its backend enqueue is in flight', async () => { + const initialGeneration = currentDownloadLifecycleGeneration('late'); useDownloadStore.setState({ downloads: [ { id: 'late', url: 'http://test', fileName: 'late.bin', destination: '/tmp', status: 'queued', category: 'Other', dateAdded: '', queueId: 'MAIN', hasBeenDispatched: false }, @@ -1452,7 +1454,7 @@ describe('useDownloadStore', () => { expect( vi.mocked(ipc.invokeCommand).mock.calls.some(([command, args]) => command === 'remove_download' - && (args as { expectedLifecycleGeneration?: string })?.expectedLifecycleGeneration === '0' + && (args as { expectedLifecycleGeneration?: string })?.expectedLifecycleGeneration === initialGeneration ) ).toBe(true); }); @@ -1662,6 +1664,7 @@ describe('useDownloadStore', () => { it('resumeDownload unregisters ID and re-dispatches if un-resumable', async () => { let enqueueGeneration: string | undefined; + const initialGeneration = BigInt(currentDownloadLifecycleGeneration('resume-generation')); useDownloadStore.setState({ downloads: [ { id: 'resume-generation', url: 'http://test1', fileName: 'f1', destination: '/tmp', status: 'paused', category: 'Other', dateAdded: '', queueId: 'MAIN', hasBeenDispatched: true }, @@ -1689,7 +1692,7 @@ describe('useDownloadStore', () => { id: 'resume-generation', queueId: 'MAIN' }); - expect(enqueueGeneration).toBe('1'); + expect(enqueueGeneration).toBe((initialGeneration + 1n).toString()); expect(useDownloadStore.getState().downloads[0].lastTry).toEqual(expect.any(String)); expect(useDownloadStore.getState().backendRegisteredIds.has('resume-generation')).toBe(true); // Re-registered by dispatchItem }); diff --git a/src/store/useDownloadStore.ts b/src/store/useDownloadStore.ts index c20f8f7..b8befca 100644 --- a/src/store/useDownloadStore.ts +++ b/src/store/useDownloadStore.ts @@ -3344,6 +3344,28 @@ export const flushDownloadPersistence = async (): Promise => { let downloadPersistenceUnsubscribe: (() => void) | null = null; +export const resetDownloadStoreModuleStateForTests = (): void => { + downloadPersistenceUnsubscribe?.(); + downloadPersistenceUnsubscribe = null; + backendDispatchPromises.clear(); + downloadLifecycleGenerations.clear(); + queueReorderPromises.clear(); + queueStartPromises.clear(); + queueControlGenerations.clear(); + queueConfigurationQueue = Promise.resolve(); + downloadLifecycleOperations.clear(); + pendingStartupResume = null; + downloadControlIntents.clear(); + persistenceRevision = 0; + committedPersistenceRevision = 0; + lastRequestedPersistenceKey = null; + lastCommittedPersistenceKey = null; + nextPersistenceSnapshot = null; + persistenceSaveInFlight = false; + persistenceWaiters = []; + downloadPersistenceReady = false; +}; + /** * Persistence is a main-webview service. Properties windows import the * download types and bridge helpers but must never install this subscription diff --git a/src/utils/dockBadge.test.ts b/src/utils/dockBadge.test.ts index 74d9efe..cec10dd 100644 --- a/src/utils/dockBadge.test.ts +++ b/src/utils/dockBadge.test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import * as ipc from '../ipc'; -import { updateDockBadge } from './dockBadge'; +import { resetDockBadgeStateForTests, updateDockBadge } from './dockBadge'; vi.mock('../ipc', () => ({ invokeCommand: vi.fn() @@ -8,6 +8,7 @@ vi.mock('../ipc', () => ({ describe('dock badge synchronization', () => { beforeEach(() => { + resetDockBadgeStateForTests(); vi.clearAllMocks(); vi.mocked(ipc.invokeCommand).mockImplementation(async command => ( command === 'begin_dock_badge_session' ? 1 : undefined diff --git a/src/utils/dockBadge.ts b/src/utils/dockBadge.ts index fb1acff..92ae1c4 100644 --- a/src/utils/dockBadge.ts +++ b/src/utils/dockBadge.ts @@ -3,6 +3,11 @@ import { invokeCommand } from '../ipc'; let dockBadgeGeneration = 0; let dockBadgeSessionRequest: Promise | null = null; +export const resetDockBadgeStateForTests = (): void => { + dockBadgeGeneration = 0; + dockBadgeSessionRequest = null; +}; + const getDockBadgeSession = (): Promise => { if (!dockBadgeSessionRequest) { const request = invokeCommand('begin_dock_badge_session'); diff --git a/vite.config.ts b/vite.config.ts index 126a34b..0fe8b15 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -68,6 +68,7 @@ export default defineConfig(async () => ({ 'import.meta.env.VITE_BUILD_ID': JSON.stringify(buildId) }, test: { + fsModuleCache: true, exclude: [ "Extensions/**", "**/node_modules/**",