From 7f2df2f6db02c22e775dd3214a414c02cf556bc5 Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Thu, 22 Jan 2026 17:12:01 -0300 Subject: [PATCH] chore: improve unit test performance --- .github/workflows/pr-validation.yml | 3 + package.json | 3 + .../layout-engine/contracts/vitest.config.mjs | 3 +- .../layout-bridge/vitest.config.ts | 5 +- .../measuring/dom/vitest.config.mjs | 3 +- .../painters/dom/vitest.config.mjs | 3 +- .../pm-adapter/src/integration.test.ts | 4 +- .../pm-adapter/vitest.config.mjs | 3 +- .../layout-engine/tests/vitest.config.mjs | 10 ++- .../src/core/commands/insertContent.test.js | 24 ++++-- .../src/extensions/table/table.test.js | 16 +++- packages/super-editor/vite.config.js | 3 + packages/superdoc/vite.config.js | 3 +- pnpm-lock.yaml | 74 ++++++++++++++----- pnpm-workspace.yaml | 1 + 15 files changed, 124 insertions(+), 34 deletions(-) diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 0315a20d6f..581d4ae83c 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -87,6 +87,9 @@ jobs: - name: Run unit tests run: pnpm test + - name: Run slow tests + run: pnpm test:slow + run-e2e-tests: runs-on: ubuntu-latest container: diff --git a/package.json b/package.json index 7a2f9bdd7c..03529ae73f 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "packageManager": "pnpm@10.25.0", "scripts": { "test": "vitest run", + "test:bench": "VITEST_BENCH=true vitest run", + "test:slow": "vitest run --root ./packages/super-editor src/tests/editor/node-import-timing.test.js", "test:debug": "pnpm --prefix packages/super-editor run test:debug", "test:inspect": "NODE_OPTIONS=\"--inspect-brk=9229\" vitest --pool threads --poolOptions.threads.singleThread", "test:all": "vitest run", @@ -73,6 +75,7 @@ "eslint-import-resolver-typescript": "catalog:", "eslint-plugin-import-x": "catalog:", "eslint-plugin-jsdoc": "catalog:", + "happy-dom": "catalog:", "husky": "catalog:", "jsdom": "catalog:", "lint-staged": "catalog:", diff --git a/packages/layout-engine/contracts/vitest.config.mjs b/packages/layout-engine/contracts/vitest.config.mjs index b9bb274962..29bb879cd9 100644 --- a/packages/layout-engine/contracts/vitest.config.mjs +++ b/packages/layout-engine/contracts/vitest.config.mjs @@ -4,7 +4,8 @@ import baseConfig from '../../../vitest.baseConfig'; export default defineConfig({ ...baseConfig, test: { - environment: 'jsdom', + // Use happy-dom for faster tests (set VITEST_DOM=jsdom to use jsdom) + environment: process.env.VITEST_DOM || 'happy-dom', include: ['src/**/*.test.ts'] } }); diff --git a/packages/layout-engine/layout-bridge/vitest.config.ts b/packages/layout-engine/layout-bridge/vitest.config.ts index 3e6e378a39..01c02b92b3 100644 --- a/packages/layout-engine/layout-bridge/vitest.config.ts +++ b/packages/layout-engine/layout-bridge/vitest.config.ts @@ -1,11 +1,14 @@ import { defineConfig } from 'vitest/config'; import baseConfig from '../../../vitest.baseConfig'; +const includeBench = process.env.VITEST_BENCH === 'true'; + export default defineConfig({ ...baseConfig, test: { environment: 'node', - include: ['test/**/*.test.ts'], + include: includeBench ? ['test/**/performance*.test.ts'] : ['test/**/*.test.ts'], + exclude: includeBench ? [] : ['test/**/performance*.test.ts'], globals: true, }, }); diff --git a/packages/layout-engine/measuring/dom/vitest.config.mjs b/packages/layout-engine/measuring/dom/vitest.config.mjs index 1a1b031058..eccf6e4dab 100644 --- a/packages/layout-engine/measuring/dom/vitest.config.mjs +++ b/packages/layout-engine/measuring/dom/vitest.config.mjs @@ -4,7 +4,8 @@ import baseConfig from '../../../../vitest.baseConfig'; export default defineConfig({ ...baseConfig, test: { - environment: 'jsdom', + // Use happy-dom for faster tests (set VITEST_DOM=jsdom to use jsdom) + environment: process.env.VITEST_DOM || 'happy-dom', include: ['src/**/*.test.ts'], setupFiles: ['./vitest.setup.ts'], }, diff --git a/packages/layout-engine/painters/dom/vitest.config.mjs b/packages/layout-engine/painters/dom/vitest.config.mjs index 74d39459a6..522217db40 100644 --- a/packages/layout-engine/painters/dom/vitest.config.mjs +++ b/packages/layout-engine/painters/dom/vitest.config.mjs @@ -4,7 +4,8 @@ import baseConfig from '../../../../vitest.baseConfig'; export default defineConfig({ ...baseConfig, test: { - environment: 'jsdom', + // Use happy-dom for faster tests (set VITEST_DOM=jsdom to use jsdom) + environment: process.env.VITEST_DOM || 'happy-dom', include: ['src/**/*.test.ts'], }, }); diff --git a/packages/layout-engine/pm-adapter/src/integration.test.ts b/packages/layout-engine/pm-adapter/src/integration.test.ts index 112219c6ff..0d1fda1d24 100644 --- a/packages/layout-engine/pm-adapter/src/integration.test.ts +++ b/packages/layout-engine/pm-adapter/src/integration.test.ts @@ -547,7 +547,9 @@ describe('PM → FlowBlock → Measure integration', () => { const fragment = mount.querySelector('.superdoc-fragment') as HTMLElement; const shadingLayer = fragment.querySelector('.superdoc-paragraph-shading') as HTMLElement; expect(shadingLayer).toBeTruthy(); - expect(shadingLayer.style.backgroundColor).toBe('rgb(170, 187, 204)'); + // Accept both rgb and hex formats (jsdom uses rgb, happy-dom uses hex) + const bgColor = shadingLayer.style.backgroundColor.toLowerCase(); + expect(bgColor === 'rgb(170, 187, 204)' || bgColor === '#aabbcc').toBe(true); document.body.removeChild(mount); }); diff --git a/packages/layout-engine/pm-adapter/vitest.config.mjs b/packages/layout-engine/pm-adapter/vitest.config.mjs index de74cddeb2..09c648b909 100644 --- a/packages/layout-engine/pm-adapter/vitest.config.mjs +++ b/packages/layout-engine/pm-adapter/vitest.config.mjs @@ -5,7 +5,8 @@ import baseConfig from '../../../vitest.baseConfig'; export default defineConfig({ ...baseConfig, test: { - environment: 'jsdom', + // Use happy-dom for faster tests (set VITEST_DOM=jsdom to use jsdom) + environment: process.env.VITEST_DOM || 'happy-dom', include: ['src/**/*.test.ts'], setupFiles: [resolve(__dirname, './vitest.setup.ts')], }, diff --git a/packages/layout-engine/tests/vitest.config.mjs b/packages/layout-engine/tests/vitest.config.mjs index e8fdfb8174..30c9b0189b 100644 --- a/packages/layout-engine/tests/vitest.config.mjs +++ b/packages/layout-engine/tests/vitest.config.mjs @@ -1,11 +1,17 @@ import { defineConfig } from 'vitest/config'; import baseConfig from '../../../vitest.baseConfig'; +const includeBench = process.env.VITEST_BENCH === 'true'; + export default defineConfig({ ...baseConfig, test: { - environment: 'jsdom', - include: ['src/**/*.test.ts', 'src/**/*.bench.ts'], + // Use happy-dom for faster tests (set VITEST_DOM=jsdom to use jsdom) + environment: process.env.VITEST_DOM || 'happy-dom', + include: includeBench + ? ['src/**/*.bench.ts'] + : ['src/**/*.test.ts'], + exclude: includeBench ? [] : ['src/**/*.bench.ts'], setupFiles: ['./vitest.setup.ts'], coverage: { enabled: false, diff --git a/packages/super-editor/src/core/commands/insertContent.test.js b/packages/super-editor/src/core/commands/insertContent.test.js index ed1eea88ef..39c1a220d8 100644 --- a/packages/super-editor/src/core/commands/insertContent.test.js +++ b/packages/super-editor/src/core/commands/insertContent.test.js @@ -166,6 +166,11 @@ describe('insertContent', () => { // Integration-style tests that use a real Editor instance to // insert markdown/HTML lists and verify exported OOXML has list numbering. describe('insertContent (integration) list export', () => { + // Cache loaded DOCX data and helpers to avoid repeated file loading + let cachedDocxData = null; + let helpers = null; + let exportHelpers = null; + const getListParagraphs = (result) => { const body = result.elements?.find((el) => el.name === 'w:body'); const paragraphs = (body?.elements || []).filter((el) => el.name === 'w:p'); @@ -189,16 +194,25 @@ describe('insertContent (integration) list export', () => { vi.resetModules(); vi.doUnmock('../helpers/contentProcessor.js'); - const { loadTestDataForEditorTests, initTestEditor } = await import('../../tests/helpers/helpers.js'); - const { docx, media, mediaFiles, fonts } = await loadTestDataForEditorTests('blank-doc.docx'); - const { editor } = initTestEditor({ content: docx, media, mediaFiles, fonts, mode: 'docx' }); + // Cache helpers and DOCX data on first call + if (!helpers) { + helpers = await import('../../tests/helpers/helpers.js'); + } + if (!cachedDocxData) { + cachedDocxData = await helpers.loadTestDataForEditorTests('blank-doc.docx'); + } + if (!exportHelpers) { + exportHelpers = await import('../../tests/export/export-helpers/index.js'); + } + + const { docx, media, mediaFiles, fonts } = cachedDocxData; + const { editor } = helpers.initTestEditor({ content: docx, media, mediaFiles, fonts, mode: 'docx' }); return editor; }; const exportFromEditorContent = async (editor) => { - const { getExportedResultWithDocContent } = await import('../../tests/export/export-helpers/index.js'); const content = editor.getJSON().content || []; - return await getExportedResultWithDocContent(content); + return await exportHelpers.getExportedResultWithDocContent(content); }; it('exports ordered list from markdown with numId/ilvl', async () => { diff --git a/packages/super-editor/src/extensions/table/table.test.js b/packages/super-editor/src/extensions/table/table.test.js index 688460ac93..f904111b16 100644 --- a/packages/super-editor/src/extensions/table/table.test.js +++ b/packages/super-editor/src/extensions/table/table.test.js @@ -1,9 +1,13 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeAll, beforeEach, afterEach } from 'vitest'; import { EditorState } from 'prosemirror-state'; import { loadTestDataForEditorTests, initTestEditor } from '@tests/helpers/helpers.js'; import { createTable } from './tableHelpers/createTable.js'; import { promises as fs } from 'fs'; +// Cache DOCX data to avoid repeated file loading +let cachedBlankDoc = null; +let cachedBordersDoc = null; + /** * Find the first table position within the provided document. * @param {import('prosemirror-model').Node} doc @@ -29,8 +33,14 @@ describe('Table commands', async () => { let templateBlockAttrs; let table; + // Load DOCX data once before all tests + beforeAll(async () => { + cachedBlankDoc = await loadTestDataForEditorTests('blank-doc.docx'); + cachedBordersDoc = await loadTestDataForEditorTests('SD-978-remove-table-borders.docx'); + }); + const setupTestTable = async () => { - let { docx, media, mediaFiles, fonts } = await loadTestDataForEditorTests('blank-doc.docx'); + const { docx, media, mediaFiles, fonts } = cachedBlankDoc; ({ editor } = initTestEditor({ content: docx, media, mediaFiles, fonts })); ({ schema } = editor); @@ -230,7 +240,7 @@ describe('Table commands', async () => { describe('table imported from docx', async () => { beforeEach(async () => { - let { docx, media, mediaFiles, fonts } = await loadTestDataForEditorTests('SD-978-remove-table-borders.docx'); + const { docx, media, mediaFiles, fonts } = cachedBordersDoc; ({ editor } = initTestEditor({ content: docx, media, mediaFiles, fonts })); tablePos = findTablePos(editor.state.doc); diff --git a/packages/super-editor/vite.config.js b/packages/super-editor/vite.config.js index 4d24e7f37d..56c6fdf34b 100644 --- a/packages/super-editor/vite.config.js +++ b/packages/super-editor/vite.config.js @@ -25,6 +25,8 @@ export default defineConfig(({ mode }) => { minWorkers, maxWorkers, globals: true, + // Keep jsdom for super-editor due to DOM API compatibility requirements + // (happy-dom has differences in HTML serialization and style computation) environment: 'jsdom', retry: 2, testTimeout: 20000, @@ -32,6 +34,7 @@ export default defineConfig(({ mode }) => { exclude: [ ...configDefaults.exclude, '**/*.spec.js', + '**/node-import-timing.test.js', // Slow test, run separately with test:slow ], coverage: { provider: 'v8', diff --git a/packages/superdoc/vite.config.js b/packages/superdoc/vite.config.js index a7be73868c..b7429ae222 100644 --- a/packages/superdoc/vite.config.js +++ b/packages/superdoc/vite.config.js @@ -94,7 +94,8 @@ export default defineConfig(({ mode, command}) => { test: { name: projectLabel, globals: true, - environment: 'jsdom', + // Use happy-dom for faster tests (set VITEST_DOM=jsdom to use jsdom) + environment: process.env.VITEST_DOM || 'happy-dom', retry: 2, testTimeout: 20000, hookTimeout: 10000, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88de72e54b..a6b803e8cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -294,7 +294,7 @@ importers: version: 8.49.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2)) eslint: specifier: 'catalog:' version: 9.39.1(jiti@2.6.1) @@ -310,6 +310,9 @@ importers: eslint-plugin-jsdoc: specifier: 'catalog:' version: 54.7.0(eslint@9.39.1(jiti@2.6.1)) + happy-dom: + specifier: ^20.3.4 + version: 20.3.4 husky: specifier: 'catalog:' version: 9.1.7 @@ -345,7 +348,7 @@ importers: version: 0.24.0(patch_hash=b69b54a87bfd9531260555cfb2fda7c94e6f75c124e3a3fae26d64272bbe86ff)(rollup@4.53.3)(vite@7.2.7(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: canvas: specifier: 'catalog:' @@ -450,7 +453,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) vue: specifier: 'catalog:' version: 3.5.25(typescript@5.9.3) @@ -475,7 +478,7 @@ importers: version: 8.49.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2)) concurrently: specifier: 'catalog:' version: 9.2.1 @@ -499,7 +502,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine: {} @@ -512,7 +515,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/layout-bridge: dependencies: @@ -549,7 +552,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/layout-engine: dependencies: @@ -595,7 +598,7 @@ importers: devDependencies: vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/pm-adapter: dependencies: @@ -635,7 +638,7 @@ importers: version: link:../painters/dom vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/style-engine: dependencies: @@ -651,7 +654,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/tests: dependencies: @@ -841,7 +844,7 @@ importers: version: 0.24.0(patch_hash=b69b54a87bfd9531260555cfb2fda7c94e6f75c124e3a3fae26d64272bbe86ff)(rollup@4.53.3)(vite@7.2.7(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) y-protocols: specifier: 'catalog:' version: 1.0.6(yjs@13.6.19) @@ -935,7 +938,7 @@ importers: version: 0.24.0(patch_hash=b69b54a87bfd9531260555cfb2fda7c94e6f75c124e3a3fae26d64272bbe86ff)(rollup@4.53.3)(vite@7.2.7(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) xml-js: specifier: 'catalog:' version: 1.6.11 @@ -944,7 +947,7 @@ importers: devDependencies: vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) shared/common: devDependencies: @@ -959,7 +962,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) vue: specifier: 'catalog:' version: 3.5.25(typescript@5.9.3) @@ -2105,6 +2108,12 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@typescript-eslint/eslint-plugin@8.49.0': resolution: {integrity: sha512-JXij0vzIaTtCwu6SxTh8qBc66kmf1xs7pI4UOiMDFVct6q86G0Zs7KRcEoJgY3Cav3x5Tq0MF5jwgpgLqgKG3A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3966,6 +3975,10 @@ packages: engines: {node: '>=0.4.7'} hasBin: true + happy-dom@20.3.4: + resolution: {integrity: sha512-rfbiwB6OKxZFIFQ7SRnCPB2WL9WhyXsFoTfecYgeCeFSOBxvkWLaXsdv5ehzJrfqwXQmDephAKWLRQoFoJwrew==} + engines: {node: '>=20.0.0'} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -6491,6 +6504,7 @@ packages: tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me temp-dir@2.0.0: resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} @@ -7069,6 +7083,11 @@ packages: whatwg-encoding@3.1.1: resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} @@ -8428,6 +8447,12 @@ snapshots: '@types/unist@3.0.3': {} + '@types/whatwg-mimetype@3.0.2': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 22.19.2 + '@typescript-eslint/eslint-plugin@8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -8743,7 +8768,7 @@ snapshots: vite: 7.2.7(@types/node@22.19.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) vue: 3.5.25(typescript@5.9.3) - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -8758,7 +8783,7 @@ snapshots: std-env: 3.10.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -10746,6 +10771,18 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 + happy-dom@20.3.4: + dependencies: + '@types/node': 22.19.2 + '@types/whatwg-mimetype': 3.0.2 + '@types/ws': 8.18.1 + entities: 4.5.0 + whatwg-mimetype: 3.0.0 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + has-bigints@1.1.0: optional: true @@ -14211,7 +14248,7 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(happy-dom@20.3.4)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.0)(postcss@8.5.6))(tsx@4.21.0)(yaml@2.8.2): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 @@ -14239,6 +14276,7 @@ snapshots: optionalDependencies: '@types/debug': 4.1.12 '@types/node': 22.19.2 + happy-dom: 20.3.4 jsdom: 27.3.0(canvas@3.2.0)(postcss@8.5.6) transitivePeerDependencies: - jiti @@ -14310,6 +14348,8 @@ snapshots: dependencies: iconv-lite: 0.6.3 + whatwg-mimetype@3.0.0: {} + whatwg-mimetype@4.0.0: {} whatwg-url@15.1.0: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 50979a0616..baaa6fc6d9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -32,6 +32,7 @@ catalog: eslint-plugin-import-x: ^4.16.1 eslint-plugin-jsdoc: ^54.1.0 eventemitter3: ^5.0.1 + happy-dom: ^20.3.4 he: ^1.2.0 husky: ^9.1.7 jimp: ^1.6.0