diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8c217f62c4..40ceb8a2611 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: uses: ./.github/workflows/test.yml continuous-release: - if: github.repository == 'vuejs/core' + if: github.repository == 'vuejs/core' && github.ref_name != 'vapor' runs-on: ubuntu-latest steps: - name: Checkout diff --git a/benchmark/.gitignore b/benchmark/.gitignore new file mode 100644 index 00000000000..484ab7e5c61 --- /dev/null +++ b/benchmark/.gitignore @@ -0,0 +1 @@ +results/* diff --git a/benchmark/client/App.vue b/benchmark/client/App.vue new file mode 100644 index 00000000000..428217aa971 --- /dev/null +++ b/benchmark/client/App.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/benchmark/client/data.ts b/benchmark/client/data.ts new file mode 100644 index 00000000000..2626bf13481 --- /dev/null +++ b/benchmark/client/data.ts @@ -0,0 +1,78 @@ +import { shallowRef } from 'vue/vapor' + +let ID = 1 + +function _random(max: number) { + return Math.round(Math.random() * 1000) % max +} + +export function buildData(count = 1000) { + const adjectives = [ + 'pretty', + 'large', + 'big', + 'small', + 'tall', + 'short', + 'long', + 'handsome', + 'plain', + 'quaint', + 'clean', + 'elegant', + 'easy', + 'angry', + 'crazy', + 'helpful', + 'mushy', + 'odd', + 'unsightly', + 'adorable', + 'important', + 'inexpensive', + 'cheap', + 'expensive', + 'fancy', + ] + const colours = [ + 'red', + 'yellow', + 'blue', + 'green', + 'pink', + 'brown', + 'purple', + 'brown', + 'white', + 'black', + 'orange', + ] + const nouns = [ + 'table', + 'chair', + 'house', + 'bbq', + 'desk', + 'car', + 'pony', + 'cookie', + 'sandwich', + 'burger', + 'pizza', + 'mouse', + 'keyboard', + ] + const data = [] + for (let i = 0; i < count; i++) + data.push({ + id: ID++, + label: shallowRef( + adjectives[_random(adjectives.length)] + + ' ' + + colours[_random(colours.length)] + + ' ' + + nouns[_random(nouns.length)], + ), + }) + return data +} diff --git a/benchmark/client/index.html b/benchmark/client/index.html new file mode 100644 index 00000000000..c3ca4c53590 --- /dev/null +++ b/benchmark/client/index.html @@ -0,0 +1,17 @@ + + + + + + Vue Vapor Benchmark + + + +
+ + + diff --git a/benchmark/client/index.ts b/benchmark/client/index.ts new file mode 100644 index 00000000000..a12f727a101 --- /dev/null +++ b/benchmark/client/index.ts @@ -0,0 +1,5 @@ +if (import.meta.env.IS_VAPOR) { + import('./vapor') +} else { + import('./vdom') +} diff --git a/benchmark/client/profiling.ts b/benchmark/client/profiling.ts new file mode 100644 index 00000000000..82d950a0f61 --- /dev/null +++ b/benchmark/client/profiling.ts @@ -0,0 +1,94 @@ +/* eslint-disable no-console */ +/* eslint-disable no-restricted-syntax */ +/* eslint-disable no-restricted-globals */ + +import { nextTick } from 'vue/vapor' + +declare namespace globalThis { + let doProfile: boolean + let reactivity: boolean + let recordTime: boolean + let times: Record +} + +globalThis.recordTime = true +globalThis.doProfile = false +globalThis.reactivity = false + +export const defer = () => new Promise(r => requestIdleCallback(r)) + +const times: Record = (globalThis.times = {}) + +export function wrap( + id: string, + fn: (...args: any[]) => any, +): (...args: any[]) => Promise { + return async (...args) => { + if (!globalThis.recordTime) { + return fn(...args) + } + + document.body.classList.remove('done') + + const { doProfile } = globalThis + await nextTick() + + doProfile && console.profile(id) + const start = performance.now() + fn(...args) + + await nextTick() + let time: number + if (globalThis.reactivity) { + time = performance.measure( + 'flushJobs-measure', + 'flushJobs-start', + 'flushJobs-end', + ).duration + performance.clearMarks() + performance.clearMeasures() + } else { + time = performance.now() - start + } + const prevTimes = times[id] || (times[id] = []) + prevTimes.push(time) + + const { min, max, median, mean, std } = compute(prevTimes) + const msg = + `${id}: min: ${min} / ` + + `max: ${max} / ` + + `median: ${median}ms / ` + + `mean: ${mean}ms / ` + + `time: ${time.toFixed(2)}ms / ` + + `std: ${std} ` + + `over ${prevTimes.length} runs` + doProfile && console.profileEnd(id) + console.log(msg) + const timeEl = document.getElementById('time')! + timeEl.textContent = msg + + document.body.classList.add('done') + } +} + +function compute(array: number[]) { + const n = array.length + const max = Math.max(...array) + const min = Math.min(...array) + const mean = array.reduce((a, b) => a + b) / n + const std = Math.sqrt( + array.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n, + ) + const median = array.slice().sort((a, b) => a - b)[Math.floor(n / 2)] + return { + max: round(max), + min: round(min), + mean: round(mean), + std: round(std), + median: round(median), + } +} + +function round(n: number) { + return +n.toFixed(2) +} diff --git a/benchmark/client/vapor.ts b/benchmark/client/vapor.ts new file mode 100644 index 00000000000..70f1d4b1b3a --- /dev/null +++ b/benchmark/client/vapor.ts @@ -0,0 +1,4 @@ +import { createVaporApp } from 'vue/vapor' +import App from './App.vue' + +createVaporApp(App as any).mount('#app') diff --git a/benchmark/client/vdom.ts b/benchmark/client/vdom.ts new file mode 100644 index 00000000000..01433bca2ac --- /dev/null +++ b/benchmark/client/vdom.ts @@ -0,0 +1,4 @@ +import { createApp } from 'vue' +import App from './App.vue' + +createApp(App).mount('#app') diff --git a/benchmark/index.js b/benchmark/index.js new file mode 100644 index 00000000000..f1a37cdff79 --- /dev/null +++ b/benchmark/index.js @@ -0,0 +1,397 @@ +// @ts-check +import path from 'node:path' +import { parseArgs } from 'node:util' +import { mkdir, rm, writeFile } from 'node:fs/promises' +import Vue from '@vitejs/plugin-vue' +import { build } from 'vite' +import connect from 'connect' +import sirv from 'sirv' +import { launch } from 'puppeteer' +import colors from 'picocolors' +import { exec, getSha } from '../scripts/utils.js' +import process from 'node:process' +import readline from 'node:readline' + +// Thanks to https://github.com/krausest/js-framework-benchmark (Apache-2.0 license) +const { + values: { + skipLib, + skipApp, + skipBench, + vdom, + noVapor, + port: portStr, + count: countStr, + warmupCount: warmupCountStr, + noHeadless, + devBuild, + }, +} = parseArgs({ + allowNegative: true, + allowPositionals: true, + options: { + skipLib: { + type: 'boolean', + short: 'l', + }, + skipApp: { + type: 'boolean', + short: 'a', + }, + skipBench: { + type: 'boolean', + short: 'b', + }, + noVapor: { + type: 'boolean', + }, + vdom: { + type: 'boolean', + short: 'v', + }, + port: { + type: 'string', + short: 'p', + default: '8193', + }, + count: { + type: 'string', + short: 'c', + default: '30', + }, + warmupCount: { + type: 'string', + short: 'w', + default: '5', + }, + noHeadless: { + type: 'boolean', + }, + devBuild: { + type: 'boolean', + short: 'd', + }, + }, +}) + +const port = +(/** @type {string}*/ (portStr)) +const count = +(/** @type {string}*/ (countStr)) +const warmupCount = +(/** @type {string}*/ (warmupCountStr)) +const sha = await getSha(true) + +if (!skipLib) { + await buildLib() +} +if (!skipApp) { + await rm('client/dist', { recursive: true }).catch(() => {}) + vdom && (await buildApp(false)) + !noVapor && (await buildApp(true)) +} +const server = startServer() + +if (!skipBench) { + await benchmark() + server.close() +} + +async function buildLib() { + console.info(colors.blue('Building lib...')) + + /** @type {import('node:child_process').SpawnOptions} */ + const options = { + cwd: path.resolve(import.meta.dirname, '..'), + stdio: 'inherit', + env: { ...process.env, BENCHMARK: 'true' }, + } + const buildOptions = devBuild ? '-df' : '-pf' + const [{ ok }, { ok: ok2 }, { ok: ok3 }, { ok: ok4 }] = await Promise.all([ + exec( + 'pnpm', + `run --silent build shared compiler-core compiler-dom compiler-vapor ${buildOptions} cjs`.split( + ' ', + ), + options, + ), + exec( + 'pnpm', + 'run --silent build compiler-sfc compiler-ssr -f cjs'.split(' '), + options, + ), + exec( + 'pnpm', + `run --silent build vue-vapor ${buildOptions} esm-browser`.split(' '), + options, + ), + exec( + 'pnpm', + `run --silent build vue ${buildOptions} esm-browser-runtime`.split(' '), + options, + ), + ]) + + if (!ok || !ok2 || !ok3 || !ok4) { + console.error('Failed to build') + process.exit(1) + } +} + +/** @param {boolean} isVapor */ +async function buildApp(isVapor) { + console.info( + colors.blue(`\nBuilding ${isVapor ? 'Vapor' : 'Virtual DOM'} app...\n`), + ) + + if (!devBuild) process.env.NODE_ENV = 'production' + const CompilerSFC = await import( + '../packages/compiler-sfc/dist/compiler-sfc.cjs.js' + ) + const prodSuffix = devBuild ? '.js' : '.prod.js' + + /** @type {any} */ + const TemplateCompiler = await import( + (isVapor + ? '../packages/compiler-vapor/dist/compiler-vapor.cjs' + : '../packages/compiler-dom/dist/compiler-dom.cjs') + prodSuffix + ) + const runtimePath = path.resolve( + import.meta.dirname, + (isVapor + ? '../packages/vue-vapor/dist/vue-vapor.esm-browser' + : '../packages/vue/dist/vue.runtime.esm-browser') + prodSuffix, + ) + + const mode = isVapor ? 'vapor' : 'vdom' + await build({ + root: './client', + base: `/${mode}`, + define: { + 'import.meta.env.IS_VAPOR': String(isVapor), + }, + build: { + minify: !devBuild && 'terser', + outDir: path.resolve('./client/dist', mode), + rollupOptions: { + onwarn(log, handler) { + if (log.code === 'INVALID_ANNOTATION') return + handler(log) + }, + }, + }, + resolve: { + alias: { + 'vue/vapor': runtimePath, + vue: runtimePath, + }, + }, + clearScreen: false, + plugins: [ + Vue({ + compiler: CompilerSFC, + template: { compiler: TemplateCompiler }, + }), + ], + }) +} + +function startServer() { + const server = connect().use(sirv('./client/dist')).listen(port) + printPort(port) + process.on('SIGTERM', () => server.close()) + return server +} + +async function benchmark() { + console.info(colors.blue(`\nStarting benchmark...`)) + + const browser = await initBrowser() + + await mkdir('results', { recursive: true }).catch(() => {}) + if (!noVapor) { + await doBench(browser, true) + } + if (vdom) { + await doBench(browser, false) + } + + await browser.close() +} + +/** + * + * @param {import('puppeteer').Browser} browser + * @param {boolean} isVapor + */ +async function doBench(browser, isVapor) { + const mode = isVapor ? 'vapor' : 'vdom' + console.info('\n\nmode:', mode) + + const page = await browser.newPage() + page.emulateCPUThrottling(4) + await page.goto(`http://localhost:${port}/${mode}`, { + waitUntil: 'networkidle0', + }) + + await forceGC() + const t = performance.now() + + console.log('warmup run') + await eachRun(() => withoutRecord(benchOnce), warmupCount) + + console.log('benchmark run') + await eachRun(benchOnce, count) + + console.info( + 'Total time:', + colors.cyan(((performance.now() - t) / 1000).toFixed(2)), + 's', + ) + const times = await getTimes() + const result = + /** @type {Record} */ + Object.fromEntries(Object.entries(times).map(([k, v]) => [k, compute(v)])) + + console.table(result) + await writeFile( + `results/benchmark-${sha}-${mode}.json`, + JSON.stringify(result, undefined, 2), + ) + await page.close() + return result + + async function benchOnce() { + await clickButton('run') // test: create rows + await clickButton('update') // partial update + await clickButton('swaprows') // swap rows + await select() // test: select row, remove row + await clickButton('clear') // clear rows + + await withoutRecord(() => clickButton('run')) + await clickButton('add') // append rows to large table + + await withoutRecord(() => clickButton('clear')) + await clickButton('runLots') // create many rows + await withoutRecord(() => clickButton('clear')) + + // TODO replace all rows + } + + function getTimes() { + return page.evaluate(() => /** @type {any} */ (globalThis).times) + } + + async function forceGC() { + await page.evaluate( + `window.gc({type:'major',execution:'sync',flavor:'last-resort'})`, + ) + } + + /** @param {() => any} fn */ + async function withoutRecord(fn) { + const currentRecordTime = await page.evaluate(() => globalThis.recordTime) + await page.evaluate(() => (globalThis.recordTime = false)) + await fn() + await page.evaluate( + currentRecordTime => (globalThis.recordTime = currentRecordTime), + currentRecordTime, + ) + } + + /** @param {string} id */ + async function clickButton(id) { + await page.click(`#${id}`) + await wait() + } + + async function select() { + for (let i = 1; i <= 10; i++) { + await page.click(`tbody > tr:nth-child(2) > td:nth-child(2) > a`) + await page.waitForSelector(`tbody > tr:nth-child(2).danger`) + await page.click(`tbody > tr:nth-child(2) > td:nth-child(3) > button`) + await wait() + } + } + + async function wait() { + await page.waitForSelector('.done') + } +} + +/** + * @param {Function} bench + * @param {number} count + */ +async function eachRun(bench, count) { + for (let i = 0; i < count; i++) { + readline.cursorTo(process.stdout, 0) + readline.clearLine(process.stdout, 0) + process.stdout.write(`${i + 1}/${count}`) + await bench() + } + if (count === 0) { + process.stdout.write('0/0 (skip)') + } + process.stdout.write('\n') +} + +async function initBrowser() { + const disableFeatures = [ + 'Translate', // avoid translation popups + 'PrivacySandboxSettings4', // avoid privacy popup + 'IPH_SidePanelGenericMenuFeature', // bookmark popup see https://github.com/krausest/js-framework-benchmark/issues/1688 + ] + + const args = [ + '--js-flags=--expose-gc', // needed for gc() function + '--no-default-browser-check', + '--disable-sync', + '--no-first-run', + '--ash-no-nudges', + '--disable-extensions', + `--disable-features=${disableFeatures.join(',')}`, + ] + + const headless = !noHeadless + console.info('headless:', headless) + const browser = await launch({ + headless: headless, + args, + }) + console.log('browser version:', colors.blue(await browser.version())) + + return browser +} + +/** @param {number[]} array */ +function compute(array) { + const n = array.length + const max = Math.max(...array) + const min = Math.min(...array) + const mean = array.reduce((a, b) => a + b) / n + const std = Math.sqrt( + array.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n, + ) + const median = array.slice().sort((a, b) => a - b)[Math.floor(n / 2)] + return { + max: round(max), + min: round(min), + mean: round(mean), + std: round(std), + median: round(median), + } +} + +/** @param {number} n */ +function round(n) { + return +n.toFixed(2) +} + +/** @param {number} port */ +function printPort(port) { + const vaporLink = !noVapor + ? `\nVapor: ${colors.blue(`http://localhost:${port}/vapor`)}` + : '' + const vdomLink = vdom + ? `\nvDom: ${colors.blue(`http://localhost:${port}/vdom`)}` + : '' + console.info(`\n\nServer started at`, vaporLink, vdomLink) +} diff --git a/benchmark/package.json b/benchmark/package.json new file mode 100644 index 00000000000..81d55005c9e --- /dev/null +++ b/benchmark/package.json @@ -0,0 +1,21 @@ +{ + "name": "benchmark", + "version": "0.0.0", + "author": "三咲智子 Kevin Deng ", + "license": "MIT", + "type": "module", + "scripts": { + "dev": "pnpm start --devBuild --noHeadless --skipBench --vdom", + "start": "node index.js" + }, + "dependencies": { + "@vitejs/plugin-vue": "https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5", + "connect": "^3.7.0", + "sirv": "^2.0.4", + "vite": "catalog:" + }, + "devDependencies": { + "@types/connect": "^3.4.38", + "terser": "^5.33.0" + } +} diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json new file mode 100644 index 00000000000..535fcf20696 --- /dev/null +++ b/benchmark/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["es2022", "dom"], + "allowJs": true, + "moduleDetection": "force", + "module": "preserve", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "types": ["node", "vite/client"], + "strict": true, + "noUnusedLocals": true, + "declaration": true, + "esModuleInterop": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true, + "noEmit": true, + "paths": { + "vue": ["../packages/vue/src"], + "@vue/*": ["../packages/*/src"] + } + }, + "include": ["**/*"] +} diff --git a/eslint.config.js b/eslint.config.js index b752b2e19f1..7282992910f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -126,6 +126,7 @@ export default tseslint.config( files: [ 'packages-private/template-explorer/**', 'packages-private/sfc-playground/**', + 'playground/**', ], rules: { 'no-restricted-globals': ['error', ...NodeGlobals], @@ -149,6 +150,7 @@ export default tseslint.config( 'eslint.config.js', 'rollup*.config.js', 'scripts/**', + 'benchmark/*', './*.{js,ts}', 'packages/*/*.js', 'packages/vue/*/*.js', diff --git a/package.json b/package.json index 2478f3a1711..9e502ec604a 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,9 @@ "build-dts": "tsc -p tsconfig.build.json --noCheck && rollup -c rollup.dts.config.js", "clean": "rimraf --glob packages/*/dist temp .eslintcache", "size": "run-s \"size-*\" && node scripts/usage-size.js", - "size-global": "node scripts/build.js vue runtime-dom -f global -p --size", + "size-global": "node scripts/build.js vue runtime-dom compiler-dom -f global -p --size", "size-esm-runtime": "node scripts/build.js vue -f esm-bundler-runtime", - "size-esm": "node scripts/build.js runtime-dom runtime-core reactivity shared -f esm-bundler", + "size-esm": "node scripts/build.js runtime-shared runtime-dom runtime-core reactivity shared runtime-vapor -f esm-bundler", "check": "tsc --incremental --noEmit", "lint": "eslint --cache .", "format": "prettier --write --cache .", @@ -29,18 +29,17 @@ "release": "node scripts/release.js", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", "dev-esm": "node scripts/dev.js -if esm-bundler-runtime", - "dev-compiler": "run-p \"dev template-explorer\" serve", - "dev-sfc": "run-s dev-sfc-prepare dev-sfc-run", - "dev-sfc-prepare": "node scripts/pre-dev-sfc.js || npm run build-all-cjs", - "dev-sfc-serve": "vite packages-private/sfc-playground --host", - "dev-sfc-run": "run-p \"dev compiler-sfc -f esm-browser\" \"dev vue -if esm-bundler-runtime\" \"dev vue -ipf esm-browser-runtime\" \"dev server-renderer -if esm-bundler\" dev-sfc-serve", + "dev-prepare-cjs": "node scripts/prepare-cjs.js || npm run build-all-cjs", + "dev-compiler": "run-p \"dev template-explorer\" serve open", + "dev-sfc": "run-s dev-prepare-cjs dev-sfc-run", + "dev-sfc-serve": "vite packages-private/sfc-playground", + "dev-sfc-run": "run-p \"dev compiler-sfc -f esm-browser\" \"dev vue -if vapor\" \"dev vue -ipf vapor\" \"dev server-renderer -if esm-bundler\" dev-sfc-serve", + "dev-vapor": "pnpm -C playground run dev", "serve": "serve", "open": "open http://localhost:3000/packages-private/template-explorer/local.html", - "build-sfc-playground": "run-s build-all-cjs build-runtime-esm build-browser-esm build-ssr-esm build-sfc-playground-self", + "build-sfc-playground": "run-s build-all-cjs build-all-esm build-sfc-playground-self", "build-all-cjs": "node scripts/build.js vue runtime compiler reactivity shared -af cjs", - "build-runtime-esm": "node scripts/build.js runtime reactivity shared -af esm-bundler && node scripts/build.js vue -f esm-bundler-runtime && node scripts/build.js vue -f esm-browser-runtime", - "build-browser-esm": "node scripts/build.js runtime reactivity shared -af esm-bundler && node scripts/build.js vue -f esm-bundler && node scripts/build.js vue -f esm-browser", - "build-ssr-esm": "node scripts/build.js compiler-sfc server-renderer -f esm-browser", + "build-all-esm": "node scripts/build.js runtime reactivity shared -af esm-bundler && node scripts/build.js vue -f esm-bundler+esm-browser+esm-bundler-runtime+esm-browser-runtime+vapor && node scripts/build.js compiler-sfc server-renderer -f esm-browser", "build-sfc-playground-self": "cd packages-private/sfc-playground && npm run build", "preinstall": "npx only-allow pnpm", "postinstall": "simple-git-hooks" @@ -75,6 +74,7 @@ "@types/semver": "^7.5.8", "@types/serve-handler": "^6.1.4", "@vitest/coverage-v8": "^2.1.1", + "@vitest/ui": "^2.1.1", "@vue/consolidate": "1.0.0", "conventional-changelog-cli": "^5.0.0", "enquirer": "^2.4.1", diff --git a/packages-private/sfc-playground/src/App.vue b/packages-private/sfc-playground/src/App.vue index d163b1a3ee6..2d4069318ae 100644 --- a/packages-private/sfc-playground/src/App.vue +++ b/packages-private/sfc-playground/src/App.vue @@ -1,8 +1,15 @@ + + diff --git a/packages-private/sfc-playground/vite.config.ts b/packages-private/sfc-playground/vite.config.ts index 2e77f1970a7..c1a40fd1ca9 100644 --- a/packages-private/sfc-playground/vite.config.ts +++ b/packages-private/sfc-playground/vite.config.ts @@ -53,6 +53,8 @@ function copyVuePlugin(): Plugin { copyFile(`vue/dist/vue.esm-browser.prod.js`) copyFile(`vue/dist/vue.runtime.esm-browser.js`) copyFile(`vue/dist/vue.runtime.esm-browser.prod.js`) + copyFile(`vue/dist/vue.runtime-with-vapor.esm-browser.js`) + copyFile(`vue/dist/vue.runtime-with-vapor.esm-browser.prod.js`) copyFile(`server-renderer/dist/server-renderer.esm-browser.js`) }, } diff --git a/packages-private/template-explorer/package.json b/packages-private/template-explorer/package.json index e8bdf0bccbb..fafca266402 100644 --- a/packages-private/template-explorer/package.json +++ b/packages-private/template-explorer/package.json @@ -11,6 +11,7 @@ "enableNonBrowserBranches": true }, "dependencies": { + "@vue/compiler-vapor": "workspace:^", "monaco-editor": "^0.52.0", "source-map-js": "^1.2.1" } diff --git a/packages-private/template-explorer/src/index.ts b/packages-private/template-explorer/src/index.ts index 988712d623c..96619b5a311 100644 --- a/packages-private/template-explorer/src/index.ts +++ b/packages-private/template-explorer/src/index.ts @@ -1,15 +1,18 @@ import type * as m from 'monaco-editor' +import type { CompilerError } from '@vue/compiler-dom' +import { compile } from '@vue/compiler-dom' import { - type CompilerError, type CompilerOptions, - compile, -} from '@vue/compiler-dom' -import { compile as ssrCompile } from '@vue/compiler-ssr' + compile as vaporCompile, +} from '@vue/compiler-vapor' +// import { compile as ssrCompile } from '@vue/compiler-ssr' + import { compilerOptions, defaultOptions, initOptions, ssrMode, + vaporMode, } from './options' import { toRaw, watchEffect } from '@vue/runtime-dom' import { SourceMapConsumer } from 'source-map-js' @@ -77,10 +80,16 @@ window.init = () => { console.clear() try { const errors: CompilerError[] = [] - const compileFn = ssrMode.value ? ssrCompile : compile + const compileFn = /* ssrMode.value ? ssrCompile : */ ( + vaporMode.value ? vaporCompile : compile + ) as typeof vaporCompile const start = performance.now() const { code, ast, map } = compileFn(source, { ...compilerOptions, + prefixIdentifiers: + compilerOptions.prefixIdentifiers || + compilerOptions.mode === 'module' || + compilerOptions.ssr, filename: 'ExampleTemplate.vue', sourceMap: true, onError: err => { diff --git a/packages-private/template-explorer/src/options.ts b/packages-private/template-explorer/src/options.ts index e3cc6173a8a..341e885c083 100644 --- a/packages-private/template-explorer/src/options.ts +++ b/packages-private/template-explorer/src/options.ts @@ -1,8 +1,9 @@ import { createApp, h, reactive, ref } from 'vue' -import type { CompilerOptions } from '@vue/compiler-dom' +import type { CompilerOptions } from '@vue/compiler-vapor' import { BindingTypes } from '@vue/compiler-core' export const ssrMode = ref(false) +export const vaporMode = ref(true) export const defaultOptions: CompilerOptions = { mode: 'module', @@ -39,11 +40,11 @@ const App = { compilerOptions.prefixIdentifiers || compilerOptions.mode === 'module' return [ - h('h1', `Vue 3 Template Explorer`), + h('h1', `Vue Template Explorer`), h( 'a', { - href: `https://github.com/vuejs/core/tree/${__COMMIT__}`, + href: `https://github.com/vuejs/vue/tree/${__COMMIT__}`, target: `_blank`, }, `@${__COMMIT__}`, @@ -222,6 +223,18 @@ const App = { }), h('label', { for: 'compat' }, 'v2 compat mode'), ]), + + h('li', [ + h('input', { + type: 'checkbox', + id: 'vapor', + checked: vaporMode.value, + onChange(e: Event) { + vaporMode.value = (e.target as HTMLInputElement).checked + }, + }), + h('label', { for: 'vapor' }, 'vapor'), + ]), ]), ]), ] diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index 2d6df9d9010..bae13372a98 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -86,6 +86,13 @@ export interface Position { column: number } +export type AllNode = + | ParentNode + | ExpressionNode + | TemplateChildNode + | AttributeNode + | DirectiveNode + export type ParentNode = RootNode | ElementNode | IfBranchNode | ForNode export type ExpressionNode = SimpleExpressionNode | CompoundExpressionNode diff --git a/packages/compiler-core/src/babelUtils.ts b/packages/compiler-core/src/babelUtils.ts index 52fabeea896..f81f2691570 100644 --- a/packages/compiler-core/src/babelUtils.ts +++ b/packages/compiler-core/src/babelUtils.ts @@ -308,8 +308,8 @@ export const isFunctionType = (node: Node): node is Function => { return /Function(?:Expression|Declaration)$|Method$/.test(node.type) } -export const isStaticProperty = (node: Node): node is ObjectProperty => - node && +export const isStaticProperty = (node?: Node): node is ObjectProperty => + !!node && (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') && !node.computed @@ -510,3 +510,79 @@ export function unwrapTSNode(node: Node): Node { return node } } + +export function isStaticNode(node: Node): boolean { + node = unwrapTSNode(node) + + switch (node.type) { + case 'UnaryExpression': // void 0, !true + return isStaticNode(node.argument) + + case 'LogicalExpression': // 1 > 2 + case 'BinaryExpression': // 1 + 2 + return isStaticNode(node.left) && isStaticNode(node.right) + + case 'ConditionalExpression': { + // 1 ? 2 : 3 + return ( + isStaticNode(node.test) && + isStaticNode(node.consequent) && + isStaticNode(node.alternate) + ) + } + + case 'SequenceExpression': // (1, 2) + case 'TemplateLiteral': // `foo${1}` + return node.expressions.every(expr => isStaticNode(expr)) + + case 'ParenthesizedExpression': // (1) + return isStaticNode(node.expression) + + case 'StringLiteral': + case 'NumericLiteral': + case 'BooleanLiteral': + case 'NullLiteral': + case 'BigIntLiteral': + return true + } + return false +} + +export function isConstantNode( + node: Node, + onIdentifier: (name: string) => boolean, +): boolean { + if (isStaticNode(node)) return true + + node = unwrapTSNode(node) + switch (node.type) { + case 'Identifier': + return onIdentifier(node.name) + case 'RegExpLiteral': + return true + case 'ObjectExpression': + return node.properties.every(prop => { + // { bar() {} } object methods are not considered static nodes + if (prop.type === 'ObjectMethod') return false + // { ...{ foo: 1 } } + if (prop.type === 'SpreadElement') + return isConstantNode(prop.argument, onIdentifier) + // { foo: 1 } + return ( + (!prop.computed || isConstantNode(prop.key, onIdentifier)) && + isConstantNode(prop.value, onIdentifier) + ) + }) + case 'ArrayExpression': + return node.elements.every(element => { + // [1, , 3] + if (element === null) return true + // [1, ...[2, 3]] + if (element.type === 'SpreadElement') + return isConstantNode(element.argument, onIdentifier) + // [1, 2] + return isConstantNode(element, onIdentifier) + }) + } + return false +} diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index 70116cfb61a..26d0bbef23d 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -105,22 +105,38 @@ const aliasHelper = (s: symbol) => `${helperNameMap[s]}: _${helperNameMap[s]}` type CodegenNode = TemplateChildNode | JSChildNode | SSRCodegenNode -export interface CodegenResult { +export interface BaseCodegenResult { code: string preamble: string - ast: RootNode + ast: unknown map?: RawSourceMap + helpers?: Set | Set +} + +export interface CodegenResult extends BaseCodegenResult { + ast: RootNode + helpers: Set } -enum NewlineType { +export enum NewlineType { + /** Start with `\n` */ Start = 0, + /** Ends with `\n` */ End = -1, + /** No `\n` included */ None = -2, + /** Don't know, calc it */ Unknown = -3, } export interface CodegenContext - extends Omit, 'bindingMetadata' | 'inline'> { + extends Omit< + Required, + | 'bindingMetadata' + | 'inline' + | 'vaporRuntimeModuleName' + | 'expressionPlugins' + > { source: string code: string line: number @@ -398,6 +414,7 @@ export function generate( code: context.code, preamble: isSetupInlined ? preambleContext.code : ``, map: context.map ? context.map.toJSON() : undefined, + helpers: ast.helpers, } } diff --git a/packages/compiler-core/src/index.ts b/packages/compiler-core/src/index.ts index 29e5f681300..36ed73eab92 100644 --- a/packages/compiler-core/src/index.ts +++ b/packages/compiler-core/src/index.ts @@ -23,15 +23,19 @@ export { } from './transform' export { generate, + NewlineType, type CodegenContext, type CodegenResult, type CodegenSourceMapGenerator, type RawSourceMap, + type BaseCodegenResult, } from './codegen' export { ErrorCodes, errorMessages, createCompilerError, + defaultOnError, + defaultOnWarn, type CoreCompilerError, type CompilerError, } from './errors' @@ -52,6 +56,7 @@ export { transformExpression, processExpression, stringifyExpression, + isLiteralWhitelisted, } from './transforms/transformExpression' export { buildSlots, @@ -75,4 +80,5 @@ export { checkCompatEnabled, warnDeprecation, CompilerDeprecationTypes, + type CompilerCompatOptions, } from './compat/compatConfig' diff --git a/packages/compiler-core/src/options.ts b/packages/compiler-core/src/options.ts index 1de865f42eb..9983071609e 100644 --- a/packages/compiler-core/src/options.ts +++ b/packages/compiler-core/src/options.ts @@ -174,6 +174,12 @@ interface SharedTransformCodegenOptions { * @default mode === 'module' */ prefixIdentifiers?: boolean + /** + * A list of parser plugins to enable for `@babel/parser`, which is used to + * parse expressions in bindings and interpolations. + * https://babeljs.io/docs/en/next/babel-parser#plugins + */ + expressionPlugins?: ParserPlugin[] /** * Control whether generate SSR-optimized render functions instead. * The resulting function must be attached to the component via the @@ -272,12 +278,6 @@ export interface TransformOptions * @default false */ cacheHandlers?: boolean - /** - * A list of parser plugins to enable for `@babel/parser`, which is used to - * parse expressions in bindings and interpolations. - * https://babeljs.io/docs/en/next/babel-parser#plugins - */ - expressionPlugins?: ParserPlugin[] /** * SFC scoped styles ID */ diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts index 9ae8897e674..9012c2701f7 100644 --- a/packages/compiler-core/src/transforms/transformExpression.ts +++ b/packages/compiler-core/src/transforms/transformExpression.ts @@ -44,7 +44,8 @@ import { parseExpression } from '@babel/parser' import { IS_REF, UNREF } from '../runtimeHelpers' import { BindingTypes } from '../options' -const isLiteralWhitelisted = /*@__PURE__*/ makeMap('true,false,null,this') +export const isLiteralWhitelisted: (key: string) => boolean = + /*@__PURE__*/ makeMap('true,false,null,this') export const transformExpression: NodeTransform = (node, context) => { if (node.type === NodeTypes.INTERPOLATION) { diff --git a/packages/compiler-core/src/utils.ts b/packages/compiler-core/src/utils.ts index b49d70bb2fb..b90a7018c8b 100644 --- a/packages/compiler-core/src/utils.ts +++ b/packages/compiler-core/src/utils.ts @@ -160,7 +160,7 @@ export const isMemberExpressionBrowser = (exp: ExpressionNode): boolean => { export const isMemberExpressionNode: ( exp: ExpressionNode, - context: TransformContext, + context: Pick, ) => boolean = __BROWSER__ ? (NOOP as any) : (exp, context) => { @@ -185,7 +185,7 @@ export const isMemberExpressionNode: ( export const isMemberExpression: ( exp: ExpressionNode, - context: TransformContext, + context: Pick, ) => boolean = __BROWSER__ ? isMemberExpressionBrowser : isMemberExpressionNode const fnExpRE = @@ -196,7 +196,7 @@ export const isFnExpressionBrowser: (exp: ExpressionNode) => boolean = exp => export const isFnExpressionNode: ( exp: ExpressionNode, - context: TransformContext, + context: Pick, ) => boolean = __BROWSER__ ? (NOOP as any) : (exp, context) => { @@ -227,7 +227,7 @@ export const isFnExpressionNode: ( export const isFnExpression: ( exp: ExpressionNode, - context: TransformContext, + context: Pick, ) => boolean = __BROWSER__ ? isFnExpressionBrowser : isFnExpressionNode export function advancePositionWithClone( @@ -279,6 +279,7 @@ export function assert(condition: boolean, msg?: string): void { } } +/** find directive */ export function findDir( node: ElementNode, name: string | RegExp, diff --git a/packages/compiler-dom/src/errors.ts b/packages/compiler-dom/src/errors.ts index b47624840ab..15641e531af 100644 --- a/packages/compiler-dom/src/errors.ts +++ b/packages/compiler-dom/src/errors.ts @@ -48,7 +48,7 @@ if (__TEST__) { } } -export const DOMErrorMessages: { [code: number]: string } = { +export const DOMErrorMessages: Record = { [DOMErrorCodes.X_V_HTML_NO_EXPRESSION]: `v-html is missing expression.`, [DOMErrorCodes.X_V_HTML_WITH_CHILDREN]: `v-html will override element children.`, [DOMErrorCodes.X_V_TEXT_NO_EXPRESSION]: `v-text is missing expression.`, @@ -60,4 +60,7 @@ export const DOMErrorMessages: { [code: number]: string } = { [DOMErrorCodes.X_V_SHOW_NO_EXPRESSION]: `v-show is missing expression.`, [DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN]: ` expects exactly one child element or component.`, [DOMErrorCodes.X_IGNORED_SIDE_EFFECT_TAG]: `Tags with side effect ( + `) expect(bindings).toStrictEqual({ __propsAliases: { @@ -173,6 +174,7 @@ describe('sfc reactive props destructure', () => { "foo:bar": { type: String, required: true, default: 'foo-bar' }, "onUpdate:modelValue": { type: Function, required: true } },`) + expect(content).toMatch(`__props.foo`) assertCode(content) }) diff --git a/packages/compiler-sfc/package.json b/packages/compiler-sfc/package.json index a9a638f5384..d6db266314e 100644 --- a/packages/compiler-sfc/package.json +++ b/packages/compiler-sfc/package.json @@ -46,6 +46,7 @@ "@vue/compiler-core": "workspace:*", "@vue/compiler-dom": "workspace:*", "@vue/compiler-ssr": "workspace:*", + "@vue/compiler-vapor": "workspace:*", "@vue/shared": "workspace:*", "estree-walker": "catalog:", "magic-string": "catalog:", diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index fee05beed96..798e7465071 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -2,6 +2,7 @@ import { BindingTypes, UNREF, isFunctionType, + isStaticNode, unwrapTSNode, walkIdentifiers, } from '@vue/compiler-dom' @@ -28,7 +29,7 @@ import { normalScriptDefaultVar, processNormalScript, } from './script/normalScript' -import { CSS_VARS_HELPER, genCssVarsCode } from './style/cssVars' +import { genCssVarsCode, getCssVarsHelper } from './style/cssVars' import { type SFCTemplateCompileOptions, compileTemplate, @@ -125,6 +126,10 @@ export interface SFCScriptCompileOptions { * Transform Vue SFCs into custom elements. */ customElement?: boolean | ((filename: string) => boolean) + /** + * Force to use of Vapor mode. + */ + vapor?: boolean } export interface ImportBinding { @@ -169,6 +174,7 @@ export function compileScript( const scopeId = options.id ? options.id.replace(/^data-v-/, '') : '' const scriptLang = script && script.lang const scriptSetupLang = scriptSetup && scriptSetup.lang + const vapor = sfc.vapor || options.vapor let refBindings: string[] | undefined @@ -753,7 +759,7 @@ export function compileScript( // no need to do this when targeting SSR !options.templateOptions?.ssr ) { - ctx.helperImports.add(CSS_VARS_HELPER) + ctx.helperImports.add(getCssVarsHelper(vapor)) ctx.helperImports.add('unref') ctx.s.prependLeft( startOffset, @@ -762,6 +768,7 @@ export function compileScript( ctx.bindingMetadata, scopeId, !!options.isProd, + vapor, )}\n`, ) } @@ -866,7 +873,7 @@ export function compileScript( } // inline render function mode - we are going to compile the template and // inline it right here - const { code, ast, preamble, tips, errors } = compileTemplate({ + const { code, preamble, tips, errors, helpers } = compileTemplate({ filename, ast: sfc.template.ast, source: sfc.template.content, @@ -911,7 +918,7 @@ export function compileScript( // avoid duplicated unref import // as this may get injected by the render function preamble OR the // css vars codegen - if (ast && ast.helpers.has(UNREF)) { + if (helpers && helpers.has(UNREF)) { ctx.helperImports.delete('unref') } returned = code @@ -931,7 +938,11 @@ export function compileScript( `\n}\n\n`, ) } else { - ctx.s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`) + ctx.s.appendRight( + endOffset, + // vapor mode generates its own return when inlined + `\n${vapor ? `` : `return `}${returned}\n}\n\n`, + ) } // 10. finalize default export @@ -940,6 +951,9 @@ export function compileScript( : `export default` let runtimeOptions = `` + if (vapor) { + runtimeOptions += `\n vapor: true,` + } if (!ctx.hasDefaultExportName && filename && filename !== DEFAULT_FILENAME) { const match = filename.match(/([^/\\]+)\.\w+$/) if (match) { @@ -980,7 +994,7 @@ export function compileScript( ctx.s.prependLeft( startOffset, `\n${genDefaultAs} /*@__PURE__*/${ctx.helper( - `defineComponent`, + vapor ? `defineVaporComponent` : `defineComponent`, )}({${def}${runtimeOptions}\n ${ hasAwait ? `async ` : `` }setup(${args}) {\n${exposeCall}`, @@ -1254,40 +1268,3 @@ function canNeverBeRef(node: Node, userReactiveImport?: string): boolean { return false } } - -function isStaticNode(node: Node): boolean { - node = unwrapTSNode(node) - - switch (node.type) { - case 'UnaryExpression': // void 0, !true - return isStaticNode(node.argument) - - case 'LogicalExpression': // 1 > 2 - case 'BinaryExpression': // 1 + 2 - return isStaticNode(node.left) && isStaticNode(node.right) - - case 'ConditionalExpression': { - // 1 ? 2 : 3 - return ( - isStaticNode(node.test) && - isStaticNode(node.consequent) && - isStaticNode(node.alternate) - ) - } - - case 'SequenceExpression': // (1, 2) - case 'TemplateLiteral': // `foo${1}` - return node.expressions.every(expr => isStaticNode(expr)) - - case 'ParenthesizedExpression': // (1) - return isStaticNode(node.expression) - - case 'StringLiteral': - case 'NumericLiteral': - case 'BooleanLiteral': - case 'NullLiteral': - case 'BigIntLiteral': - return true - } - return false -} diff --git a/packages/compiler-sfc/src/compileTemplate.ts b/packages/compiler-sfc/src/compileTemplate.ts index 322b1570e1a..bd69fb2cc9f 100644 --- a/packages/compiler-sfc/src/compileTemplate.ts +++ b/packages/compiler-sfc/src/compileTemplate.ts @@ -1,5 +1,5 @@ import { - type CodegenResult, + type BaseCodegenResult, type CompilerError, type CompilerOptions, type ElementNode, @@ -24,24 +24,29 @@ import { } from './template/transformSrcset' import { generateCodeFrame, isObject } from '@vue/shared' import * as CompilerDOM from '@vue/compiler-dom' +import * as CompilerVapor from '@vue/compiler-vapor' import * as CompilerSSR from '@vue/compiler-ssr' import consolidate from '@vue/consolidate' import { warnOnce } from './warn' import { genCssVarsFromList } from './style/cssVars' export interface TemplateCompiler { - compile(source: string | RootNode, options: CompilerOptions): CodegenResult + compile( + source: string | RootNode, + options: CompilerOptions, + ): BaseCodegenResult parse(template: string, options: ParserOptions): RootNode } export interface SFCTemplateCompileResults { code: string - ast?: RootNode + ast?: unknown preamble?: string source: string tips: string[] errors: (string | CompilerError)[] map?: RawSourceMap + helpers?: Set } export interface SFCTemplateCompileOptions { @@ -52,6 +57,7 @@ export interface SFCTemplateCompileOptions { scoped?: boolean slotted?: boolean isProd?: boolean + vapor?: boolean ssr?: boolean ssrCssVars?: string[] inMap?: RawSourceMap @@ -168,6 +174,7 @@ function doCompileTemplate({ source, ast: inAST, ssr = false, + vapor = false, ssrCssVars, isProd = false, compiler, @@ -202,7 +209,12 @@ function doCompileTemplate({ const shortId = id.replace(/^data-v-/, '') const longId = `data-v-${shortId}` - const defaultCompiler = ssr ? (CompilerSSR as TemplateCompiler) : CompilerDOM + const defaultCompiler = vapor + ? // TODO ssr + (CompilerVapor as TemplateCompiler) + : ssr + ? (CompilerSSR as TemplateCompiler) + : CompilerDOM compiler = compiler || defaultCompiler if (compiler !== defaultCompiler) { @@ -227,25 +239,30 @@ function doCompileTemplate({ inAST = createRoot(template.children, inAST.source) } - let { code, ast, preamble, map } = compiler.compile(inAST || source, { - mode: 'module', - prefixIdentifiers: true, - hoistStatic: true, - cacheHandlers: true, - ssrCssVars: - ssr && ssrCssVars && ssrCssVars.length - ? genCssVarsFromList(ssrCssVars, shortId, isProd, true) - : '', - scopeId: scoped ? longId : undefined, - slotted, - sourceMap: true, - ...compilerOptions, - hmr: !isProd, - nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []), - filename, - onError: e => errors.push(e), - onWarn: w => warnings.push(w), - }) + let { code, ast, preamble, map, helpers } = compiler.compile( + inAST || source, + { + mode: 'module', + prefixIdentifiers: true, + hoistStatic: true, + cacheHandlers: true, + ssrCssVars: + ssr && ssrCssVars && ssrCssVars.length + ? genCssVarsFromList(ssrCssVars, shortId, isProd, true) + : '', + scopeId: scoped ? longId : undefined, + slotted, + sourceMap: true, + ...compilerOptions, + hmr: !isProd, + nodeTransforms: nodeTransforms.concat( + compilerOptions.nodeTransforms || [], + ), + filename, + onError: e => errors.push(e), + onWarn: w => warnings.push(w), + }, + ) // inMap should be the map produced by ./parse.ts which is a simple line-only // mapping. If it is present, we need to adjust the final map and errors to @@ -271,7 +288,16 @@ function doCompileTemplate({ return msg }) - return { code, ast, preamble, source, errors, tips, map } + return { + code, + ast, + preamble, + source, + errors, + tips, + map, + helpers, + } } function mapLines(oldMap: RawSourceMap, newMap: RawSourceMap): RawSourceMap { diff --git a/packages/compiler-sfc/src/parse.ts b/packages/compiler-sfc/src/parse.ts index c8be865508f..739b455d066 100644 --- a/packages/compiler-sfc/src/parse.ts +++ b/packages/compiler-sfc/src/parse.ts @@ -84,6 +84,8 @@ export interface SFCDescriptor { */ slotted: boolean + vapor: boolean + /** * compare with an existing descriptor to determine whether HMR should perform * a reload vs. re-render. @@ -137,6 +139,7 @@ export function parse( customBlocks: [], cssVars: [], slotted: false, + vapor: false, shouldForceReload: prevImports => hmrShouldReload(prevImports, descriptor), } @@ -171,6 +174,7 @@ export function parse( source, false, ) as SFCTemplateBlock) + descriptor.vapor ||= !!templateBlock.attrs.vapor if (!templateBlock.attrs.src) { templateBlock.ast = createRoot(node.children, source) @@ -195,6 +199,7 @@ export function parse( break case 'script': const scriptBlock = createBlock(node, source, pad) as SFCScriptBlock + descriptor.vapor ||= !!scriptBlock.attrs.vapor const isSetup = !!scriptBlock.attrs.setup if (isSetup && !descriptor.scriptSetup) { descriptor.scriptSetup = scriptBlock diff --git a/packages/compiler-sfc/src/script/defineProps.ts b/packages/compiler-sfc/src/script/defineProps.ts index 9a4880a1a54..ac5226168e4 100644 --- a/packages/compiler-sfc/src/script/defineProps.ts +++ b/packages/compiler-sfc/src/script/defineProps.ts @@ -79,6 +79,15 @@ export function processDefineProps( ) } ctx.propsTypeDecl = node.typeParameters.params[0] + // register bindings + const { props } = resolveTypeElements(ctx, ctx.propsTypeDecl) + if (props) { + for (const key in props) { + if (!(key in ctx.bindingMetadata)) { + ctx.bindingMetadata[key] = BindingTypes.PROPS + } + } + } } // handle props destructure @@ -190,10 +199,6 @@ export function extractRuntimeProps( for (const prop of props) { propStrings.push(genRuntimePropFromType(ctx, prop, hasStaticDefaults)) - // register bindings - if ('bindingMetadata' in ctx && !(prop.key in ctx.bindingMetadata)) { - ctx.bindingMetadata[prop.key] = BindingTypes.PROPS - } } let propsDecls = `{ diff --git a/packages/compiler-sfc/src/style/cssVars.ts b/packages/compiler-sfc/src/style/cssVars.ts index 0397c7d790a..95a7d53c8ae 100644 --- a/packages/compiler-sfc/src/style/cssVars.ts +++ b/packages/compiler-sfc/src/style/cssVars.ts @@ -10,10 +10,14 @@ import { import type { SFCDescriptor } from '../parse' import type { PluginCreator } from 'postcss' import hash from 'hash-sum' -import { getEscapedCssVarName } from '@vue/shared' +import { capitalize, getEscapedCssVarName } from '@vue/shared' export const CSS_VARS_HELPER = `useCssVars` +export function getCssVarsHelper(vapor: boolean | undefined): string { + return vapor ? `vapor${capitalize(CSS_VARS_HELPER)}` : CSS_VARS_HELPER +} + export function genCssVarsFromList( vars: string[], id: string, @@ -162,6 +166,7 @@ export function genCssVarsCode( bindings: BindingMetadata, id: string, isProd: boolean, + vapor?: boolean, ) { const varsExp = genCssVarsFromList(vars, id, isProd) const exp = createSimpleExpression(varsExp, false) @@ -182,7 +187,7 @@ export function genCssVarsCode( }) .join('') - return `_${CSS_VARS_HELPER}(_ctx => (${transformedString}))` + return `_${getCssVarsHelper(vapor)}(_ctx => (${transformedString}))` } // + + diff --git a/playground/package.json b/playground/package.json new file mode 100644 index 00000000000..ff092f73af3 --- /dev/null +++ b/playground/package.json @@ -0,0 +1,22 @@ +{ + "name": "playground", + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "node ./setup/vite.js", + "build": "vite build -c vite.prod.config.ts", + "prepreview": "cd ../ && pnpm run build runtime-vapor -f esm-bundler", + "preview": "pnpm run build && vite preview -c vite.prod.config.ts" + }, + "dependencies": { + "@vueuse/core": "^11.1.0", + "vue": "workspace:*" + }, + "devDependencies": { + "@vitejs/plugin-vue": "https://pkg.pr.new/@vitejs/plugin-vue@481bcd4", + "@vue/compiler-sfc": "workspace:*", + "vite": "catalog:", + "vite-hyper-config": "^0.4.0", + "vite-plugin-inspect": "^0.8.7" + } +} diff --git a/playground/setup/dev.js b/playground/setup/dev.js new file mode 100644 index 00000000000..ab1c59e5e59 --- /dev/null +++ b/playground/setup/dev.js @@ -0,0 +1,66 @@ +// @ts-check +import path from 'node:path' + +const resolve = (/** @type {string} */ p) => + path.resolve(import.meta.dirname, '../../packages', p) + +/** + * @param {Object} [env] + * @param {boolean} [env.browser] + * @returns {import('vite').Plugin} + */ +export function DevPlugin({ browser = false } = {}) { + return { + name: 'dev-plugin', + config() { + return { + resolve: { + alias: { + vue: resolve('vue/src/runtime-with-vapor.ts'), + + '@vue/runtime-core': resolve('runtime-core/src'), + '@vue/runtime-dom': resolve('runtime-dom/src'), + '@vue/runtime-vapor': resolve('runtime-vapor/src'), + + '@vue/compiler-core': resolve('compiler-core/src'), + '@vue/compiler-dom': resolve('compiler-dom/src'), + '@vue/compiler-vapor': resolve('compiler-vapor/src'), + + '@vue/compiler-sfc': resolve('compiler-sfc/src'), + '@vue/compiler-ssr': resolve('compiler-ssr/src'), + + '@vue/reactivity': resolve('reactivity/src'), + '@vue/shared': resolve('shared/src'), + '@vue/runtime-shared': resolve('runtime-shared/src'), + }, + }, + define: { + __COMMIT__: `"__COMMIT__"`, + __VERSION__: `"0.0.0"`, + __DEV__: `true`, + // this is only used during Vue's internal tests + __TEST__: `false`, + // If the build is expected to run directly in the browser (global / esm builds) + __BROWSER__: String(browser), + __GLOBAL__: String(false), + __ESM_BUNDLER__: String(true), + __ESM_BROWSER__: String(false), + // is targeting Node (SSR)? + __NODE_JS__: String(false), + // need SSR-specific branches? + __SSR__: String(false), + __BENCHMARK__: 'false', + + // 2.x compat build + __COMPAT__: String(false), + + // feature flags + __FEATURE_SUSPENSE__: `true`, + __FEATURE_OPTIONS_API__: `true`, + __FEATURE_PROD_DEVTOOLS__: `false`, + __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__: `false`, + }, + } + }, + } +} diff --git a/playground/setup/vite.js b/playground/setup/vite.js new file mode 100644 index 00000000000..e6b9a927206 --- /dev/null +++ b/playground/setup/vite.js @@ -0,0 +1,14 @@ +// @ts-check + +import { startVite } from 'vite-hyper-config' +import { DevPlugin } from './dev.js' + +startVite( + undefined, + { plugins: [DevPlugin()] }, + { + deps: { + inline: ['@vitejs/plugin-vue'], + }, + }, +) diff --git a/playground/src/.gitignore b/playground/src/.gitignore new file mode 100644 index 00000000000..2e1b9cfb780 --- /dev/null +++ b/playground/src/.gitignore @@ -0,0 +1,5 @@ +* +!.gitignore +!App.vue +!main.ts +!style.css diff --git a/playground/src/App.vue b/playground/src/App.vue new file mode 100644 index 00000000000..5795cf47e95 --- /dev/null +++ b/playground/src/App.vue @@ -0,0 +1,8 @@ + + + diff --git a/playground/src/main.ts b/playground/src/main.ts new file mode 100644 index 00000000000..9d682d9ffb6 --- /dev/null +++ b/playground/src/main.ts @@ -0,0 +1 @@ +import './_entry' diff --git a/playground/src/style.css b/playground/src/style.css new file mode 100644 index 00000000000..832e61618b0 --- /dev/null +++ b/playground/src/style.css @@ -0,0 +1,6 @@ +.red { + color: red; +} +.green { + color: green; +} diff --git a/playground/tsconfig.json b/playground/tsconfig.json new file mode 100644 index 00000000000..1b1d44c776d --- /dev/null +++ b/playground/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "isolatedDeclarations": false, + "allowJs": true + }, + "include": ["./**/*", "../packages/*/src"] +} diff --git a/playground/vite.config.ts b/playground/vite.config.ts new file mode 100644 index 00000000000..8b4b1a423f7 --- /dev/null +++ b/playground/vite.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'vite' +import Inspect from 'vite-plugin-inspect' +import { DevPlugin } from './setup/dev' +import Vue from '@vitejs/plugin-vue' +import * as CompilerSFC from '@vue/compiler-sfc' + +export default defineConfig({ + clearScreen: false, + plugins: [ + Vue({ + compiler: CompilerSFC, + }), + DevPlugin(), + Inspect(), + ], + optimizeDeps: { + exclude: ['@vueuse/core'], + }, +}) diff --git a/playground/vite.prod.config.ts b/playground/vite.prod.config.ts new file mode 100644 index 00000000000..6bafb7a772a --- /dev/null +++ b/playground/vite.prod.config.ts @@ -0,0 +1,26 @@ +import { defineConfig } from 'vite' +import Vue from '@vitejs/plugin-vue' +import * as CompilerSFC from '@vue/compiler-sfc' + +export default defineConfig({ + build: { + modulePreload: false, + target: 'esnext', + minify: 'terser', + terserOptions: { + format: { comments: false }, + compress: { + pure_getters: true, + }, + }, + }, + clearScreen: false, + plugins: [ + Vue({ + compiler: CompilerSFC, + features: { + optionsAPI: false, + }, + }), + ], +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 83a347d885b..3f7ab37c2c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,25 +8,25 @@ catalogs: default: '@babel/parser': specifier: ^7.25.3 - version: 7.25.3 + version: 7.25.6 '@babel/types': specifier: ^7.25.2 - version: 7.25.2 + version: 7.25.6 '@vitejs/plugin-vue': specifier: ^5.1.2 - version: 5.1.2 + version: 5.1.4 estree-walker: specifier: ^2.0.2 version: 2.0.2 magic-string: specifier: ^0.30.11 - version: 0.30.11 + version: 0.30.12 source-map-js: specifier: ^1.2.0 - version: 1.2.0 + version: 1.2.1 vite: specifier: ^5.4.0 - version: 5.4.0 + version: 5.4.8 importers: @@ -34,10 +34,10 @@ importers: devDependencies: '@babel/parser': specifier: 'catalog:' - version: 7.25.3 + version: 7.25.6 '@babel/types': specifier: 'catalog:' - version: 7.25.2 + version: 7.25.6 '@rollup/plugin-alias': specifier: ^5.1.1 version: 5.1.1(rollup@4.25.0) @@ -70,10 +70,13 @@ importers: version: 6.1.4 '@vitest/coverage-v8': specifier: ^2.1.1 - version: 2.1.1(vitest@2.1.1(@types/node@22.8.7)(jsdom@25.0.0)(sass@1.80.6)) + version: 2.1.1(vitest@2.1.1) '@vitest/eslint-plugin': specifier: ^1.0.1 - version: 1.1.6(@typescript-eslint/utils@8.12.2(eslint@9.14.0)(typescript@5.6.2))(eslint@9.14.0)(typescript@5.6.2)(vitest@2.1.1(@types/node@22.8.7)(jsdom@25.0.0)(sass@1.80.6)) + version: 1.1.6(@typescript-eslint/utils@8.12.2(eslint@9.14.0)(typescript@5.6.2))(eslint@9.14.0)(typescript@5.6.2)(vitest@2.1.1) + '@vitest/ui': + specifier: ^2.1.1 + version: 2.1.1(vitest@2.1.1) '@vue/consolidate': specifier: 1.0.0 version: 1.0.0 @@ -175,10 +178,32 @@ importers: version: 8.12.2(eslint@9.14.0)(typescript@5.6.2) vite: specifier: 'catalog:' - version: 5.4.0(@types/node@22.8.7)(sass@1.80.6) + version: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) vitest: specifier: ^2.1.1 - version: 2.1.1(@types/node@22.8.7)(jsdom@25.0.0)(sass@1.80.6) + version: 2.1.1(@types/node@22.8.7)(@vitest/ui@2.1.1)(jsdom@25.0.0)(sass@1.80.6)(terser@5.33.0) + + benchmark: + dependencies: + '@vitejs/plugin-vue': + specifier: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5 + version: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@3.5.13(typescript@5.6.2)) + connect: + specifier: ^3.7.0 + version: 3.7.0 + sirv: + specifier: ^2.0.4 + version: 2.0.4 + vite: + specifier: 'catalog:' + version: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) + devDependencies: + '@types/connect': + specifier: ^3.4.38 + version: 3.4.38 + terser: + specifier: ^5.33.0 + version: 5.33.0 packages-private/dts-built-test: dependencies: @@ -218,13 +243,16 @@ importers: devDependencies: '@vitejs/plugin-vue': specifier: 'catalog:' - version: 5.1.2(vite@5.4.0(@types/node@22.8.7)(sass@1.80.6))(vue@packages+vue) + version: 5.1.4(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue) vite: specifier: 'catalog:' - version: 5.4.0(@types/node@22.8.7)(sass@1.80.6) + version: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) packages-private/template-explorer: dependencies: + '@vue/compiler-vapor': + specifier: workspace:^ + version: link:../../packages/compiler-vapor monaco-editor: specifier: ^0.52.0 version: 0.52.0 @@ -236,10 +264,10 @@ importers: devDependencies: '@vitejs/plugin-vue': specifier: 'catalog:' - version: 5.1.2(vite@5.4.0(@types/node@22.8.7)(sass@1.80.6))(vue@packages+vue) + version: 5.1.4(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue) vite: specifier: 'catalog:' - version: 5.4.0(@types/node@22.8.7)(sass@1.80.6) + version: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) vue: specifier: workspace:* version: link:../../packages/vue @@ -248,7 +276,7 @@ importers: dependencies: '@babel/parser': specifier: 'catalog:' - version: 7.25.3 + version: 7.25.6 '@vue/shared': specifier: workspace:* version: link:../shared @@ -260,11 +288,11 @@ importers: version: 2.0.2 source-map-js: specifier: 'catalog:' - version: 1.2.0 + version: 1.2.1 devDependencies: '@babel/types': specifier: 'catalog:' - version: 7.25.2 + version: 7.25.6 packages/compiler-dom: dependencies: @@ -279,7 +307,7 @@ importers: dependencies: '@babel/parser': specifier: 'catalog:' - version: 7.25.3 + version: 7.25.6 '@vue/compiler-core': specifier: workspace:* version: link:../compiler-core @@ -289,6 +317,9 @@ importers: '@vue/compiler-ssr': specifier: workspace:* version: link:../compiler-ssr + '@vue/compiler-vapor': + specifier: workspace:* + version: link:../compiler-vapor '@vue/shared': specifier: workspace:* version: link:../shared @@ -297,17 +328,17 @@ importers: version: 2.0.2 magic-string: specifier: 'catalog:' - version: 0.30.11 + version: 0.30.12 postcss: specifier: ^8.4.48 version: 8.4.48 source-map-js: specifier: 'catalog:' - version: 1.2.0 + version: 1.2.1 devDependencies: '@babel/types': specifier: 'catalog:' - version: 7.25.2 + version: 7.25.6 '@vue/consolidate': specifier: ^1.0.0 version: 1.0.0 @@ -345,6 +376,18 @@ importers: specifier: workspace:* version: link:../shared + packages/compiler-vapor: + dependencies: + '@vue/compiler-dom': + specifier: workspace:* + version: link:../compiler-dom + '@vue/shared': + specifier: workspace:* + version: link:../shared + source-map-js: + specifier: ^1.0.2 + version: 1.2.0 + packages/reactivity: dependencies: '@vue/shared': @@ -388,6 +431,18 @@ importers: specifier: workspace:* version: link:../shared + packages/runtime-vapor: + dependencies: + '@vue/reactivity': + specifier: workspace:* + version: link:../reactivity + '@vue/runtime-dom': + specifier: workspace:* + version: link:../runtime-dom + '@vue/shared': + specifier: workspace:* + version: link:../shared + packages/server-renderer: dependencies: '@vue/compiler-ssr': @@ -413,6 +468,9 @@ importers: '@vue/runtime-dom': specifier: workspace:* version: link:../runtime-dom + '@vue/runtime-vapor': + specifier: workspace:* + version: link:../runtime-vapor '@vue/server-renderer': specifier: workspace:* version: link:../server-renderer @@ -427,23 +485,51 @@ importers: dependencies: '@babel/parser': specifier: 'catalog:' - version: 7.25.3 + version: 7.25.6 estree-walker: specifier: 'catalog:' version: 2.0.2 source-map-js: specifier: 'catalog:' - version: 1.2.0 + version: 1.2.1 vue: specifier: workspace:* version: link:../vue + playground: + dependencies: + '@vueuse/core': + specifier: ^11.1.0 + version: 11.1.0(vue@packages+vue) + vue: + specifier: workspace:* + version: link:../packages/vue + devDependencies: + '@vitejs/plugin-vue': + specifier: https://pkg.pr.new/@vitejs/plugin-vue@481bcd4 + version: https://pkg.pr.new/@vitejs/plugin-vue@481bcd4(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue) + '@vue/compiler-sfc': + specifier: workspace:* + version: link:../packages/compiler-sfc + vite: + specifier: 'catalog:' + version: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) + vite-hyper-config: + specifier: ^0.4.0 + version: 0.4.0(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)) + vite-plugin-inspect: + specifier: ^0.8.7 + version: 0.8.7(rollup@4.25.0)(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)) + packages: '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + '@babel/code-frame@7.24.7': resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} @@ -460,13 +546,13 @@ packages: resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.25.3': - resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} + '@babel/parser@7.25.6': + resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.25.2': - resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} + '@babel/types@7.25.6': + resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -848,6 +934,9 @@ packages: resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} @@ -949,6 +1038,9 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@polka/url@1.0.0-next.25': + resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + '@puppeteer/browsers@2.4.0': resolution: {integrity: sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==} engines: {node: '>=18'} @@ -1017,41 +1109,21 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.20.0': - resolution: {integrity: sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==} - cpu: [arm] - os: [android] - '@rollup/rollup-android-arm-eabi@4.25.0': resolution: {integrity: sha512-CC/ZqFZwlAIbU1wUPisHyV/XRc5RydFrNLtgl3dGYskdwPZdt4HERtKm50a/+DtTlKeCq9IXFEWR+P6blwjqBA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.20.0': - resolution: {integrity: sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==} - cpu: [arm64] - os: [android] - '@rollup/rollup-android-arm64@4.25.0': resolution: {integrity: sha512-/Y76tmLGUJqVBXXCfVS8Q8FJqYGhgH4wl4qTA24E9v/IJM0XvJCGQVSW1QZ4J+VURO9h8YCa28sTFacZXwK7Rg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.20.0': - resolution: {integrity: sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==} - cpu: [arm64] - os: [darwin] - '@rollup/rollup-darwin-arm64@4.25.0': resolution: {integrity: sha512-YVT6L3UrKTlC0FpCZd0MGA7NVdp7YNaEqkENbWQ7AOVOqd/7VzyHpgIpc1mIaxRAo1ZsJRH45fq8j4N63I/vvg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.20.0': - resolution: {integrity: sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==} - cpu: [x64] - os: [darwin] - '@rollup/rollup-darwin-x64@4.25.0': resolution: {integrity: sha512-ZRL+gexs3+ZmmWmGKEU43Bdn67kWnMeWXLFhcVv5Un8FQcx38yulHBA7XR2+KQdYIOtD0yZDWBCudmfj6lQJoA==} cpu: [x64] @@ -1067,121 +1139,61 @@ packages: cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.20.0': - resolution: {integrity: sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.25.0': resolution: {integrity: sha512-uD/dbLSs1BEPzg564TpRAQ/YvTnCds2XxyOndAO8nJhaQcqQGFgv/DAVko/ZHap3boCvxnzYMa3mTkV/B/3SWA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.20.0': - resolution: {integrity: sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.25.0': resolution: {integrity: sha512-ZVt/XkrDlQWegDWrwyC3l0OfAF7yeJUF4fq5RMS07YM72BlSfn2fQQ6lPyBNjt+YbczMguPiJoCfaQC2dnflpQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.20.0': - resolution: {integrity: sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.25.0': resolution: {integrity: sha512-qboZ+T0gHAW2kkSDPHxu7quaFaaBlynODXpBVnPxUgvWYaE84xgCKAPEYE+fSMd3Zv5PyFZR+L0tCdYCMAtG0A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.20.0': - resolution: {integrity: sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-musl@4.25.0': resolution: {integrity: sha512-ndWTSEmAaKr88dBuogGH2NZaxe7u2rDoArsejNslugHZ+r44NfWiwjzizVS1nUOHo+n1Z6qV3X60rqE/HlISgw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': - resolution: {integrity: sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==} - cpu: [ppc64] - os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.25.0': resolution: {integrity: sha512-BVSQvVa2v5hKwJSy6X7W1fjDex6yZnNKy3Kx1JGimccHft6HV0THTwNtC2zawtNXKUu+S5CjXslilYdKBAadzA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.20.0': - resolution: {integrity: sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==} - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.25.0': resolution: {integrity: sha512-G4hTREQrIdeV0PE2JruzI+vXdRnaK1pg64hemHq2v5fhv8C7WjVaeXc9P5i4Q5UC06d/L+zA0mszYIKl+wY8oA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.20.0': - resolution: {integrity: sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==} - cpu: [s390x] - os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.25.0': resolution: {integrity: sha512-9T/w0kQ+upxdkFL9zPVB6zy9vWW1deA3g8IauJxojN4bnz5FwSsUAD034KpXIVX5j5p/rn6XqumBMxfRkcHapQ==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.20.0': - resolution: {integrity: sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==} - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-gnu@4.25.0': resolution: {integrity: sha512-ThcnU0EcMDn+J4B9LD++OgBYxZusuA7iemIIiz5yzEcFg04VZFzdFjuwPdlURmYPZw+fgVrFzj4CA64jSTG4Ig==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.20.0': - resolution: {integrity: sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==} - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-musl@4.25.0': resolution: {integrity: sha512-zx71aY2oQxGxAT1JShfhNG79PnjYhMC6voAjzpu/xmMjDnKNf6Nl/xv7YaB/9SIa9jDYf8RBPWEnjcdlhlv1rQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.20.0': - resolution: {integrity: sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==} - cpu: [arm64] - os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.25.0': resolution: {integrity: sha512-JT8tcjNocMs4CylWY/CxVLnv8e1lE7ff1fi6kbGocWwxDq9pj30IJ28Peb+Y8yiPNSF28oad42ApJB8oUkwGww==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.20.0': - resolution: {integrity: sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==} - cpu: [ia32] - os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.25.0': resolution: {integrity: sha512-dRLjLsO3dNOfSN6tjyVlG+Msm4IiZnGkuZ7G5NmpzwF9oOc582FZG05+UdfTbz5Jd4buK/wMb6UeHFhG18+OEg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.20.0': - resolution: {integrity: sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==} - cpu: [x64] - os: [win32] - '@rollup/rollup-win32-x64-msvc@4.25.0': resolution: {integrity: sha512-/RqrIFtLB926frMhZD0a5oDa4eFIbyNEwLLloMTEjmqfwZWXywwVVOVmwTsuyhC9HKkVEZcOOi+KV4U9wmOdlg==} cpu: [x64] @@ -1265,8 +1277,8 @@ packages: '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -1295,6 +1307,9 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} @@ -1382,8 +1397,24 @@ packages: resolution: {integrity: sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitejs/plugin-vue@5.1.2': - resolution: {integrity: sha512-nY9IwH12qeiJqumTCLJLE7IiNx7HZ39cbHaysEUd+Myvbz9KAqd2yq+U01Kab1R/H1BmiyM2ShTYlNH32Fzo3A==} + '@vitejs/plugin-vue@5.1.4': + resolution: {integrity: sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@481bcd4': + resolution: {tarball: https://pkg.pr.new/@vitejs/plugin-vue@481bcd4} + version: 5.1.5 + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5': + resolution: {tarball: https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5} + version: 5.1.4 engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 @@ -1436,16 +1467,59 @@ packages: '@vitest/spy@2.1.1': resolution: {integrity: sha512-ZM39BnZ9t/xZ/nF4UwRH5il0Sw93QnZXd9NAZGRpIgj0yvVwPpLd702s/Cx955rGaMlyBQkZJ2Ir7qyY48VZ+g==} + '@vitest/ui@2.1.1': + resolution: {integrity: sha512-IIxo2LkQDA+1TZdPLYPclzsXukBWd5dX2CKpGqH8CCt8Wh0ZuDn4+vuQ9qlppEju6/igDGzjWF/zyorfsf+nHg==} + peerDependencies: + vitest: 2.1.1 + '@vitest/utils@2.1.1': resolution: {integrity: sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==} + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + '@vue/consolidate@1.0.0': resolution: {integrity: sha512-oTyUE+QHIzLw2PpV14GD/c7EohDyP64xCniWTcqcEmTd699eFqTIwOmtDYjcO1j3QgdXoJEoWv1/cCdLrRoOfg==} engines: {node: '>= 0.12.0'} + '@vue/reactivity@3.5.13': + resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + '@vue/repl@4.4.2': resolution: {integrity: sha512-MEAsBK/YzMFGINOBzqM40XTeIYAUsg7CqvXvD5zi0rhYEQrPfEUIdexmMjdm7kVKsKmcvIHxrFK2DFC35m9kHw==} + '@vue/runtime-core@3.5.13': + resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + + '@vue/runtime-dom@3.5.13': + resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + + '@vue/server-renderer@3.5.13': + resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} + peerDependencies: + vue: 3.5.13 + + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + + '@vueuse/core@11.1.0': + resolution: {integrity: sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg==} + + '@vueuse/metadata@11.1.0': + resolution: {integrity: sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg==} + + '@vueuse/shared@11.1.0': + resolution: {integrity: sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==} + '@zeit/schemas@2.36.0': resolution: {integrity: sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==} @@ -1590,9 +1664,16 @@ packages: buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + bytes@3.0.0: resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} engines: {node: '>= 0.8'} @@ -1697,6 +1778,9 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -1714,6 +1798,10 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + connect@3.7.0: + resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} + engines: {node: '>= 0.10.0'} + constantinople@4.0.1: resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} @@ -1849,6 +1937,15 @@ packages: supports-color: optional: true + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} @@ -1867,10 +1964,22 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + degenerator@5.0.1: resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} engines: {node: '>= 14'} @@ -1901,6 +2010,9 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + emoji-regex@10.3.0: resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} @@ -1910,6 +2022,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -1932,6 +2048,9 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-stack-parser-es@0.1.5: + resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==} + es-define-property@1.0.0: resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} engines: {node: '>= 0.4'} @@ -1962,6 +2081,9 @@ packages: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -2075,6 +2197,14 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.3.0: + resolution: {integrity: sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fdir@6.4.0: resolution: {integrity: sha512-3oB133prH1o4j/L5lLW7uOCF1PlD+/It2L0eL/iAqWMB91RBbqTewABqxhj0ibBd90EEmWZq7ntIWzVaWcXTGQ==} peerDependencies: @@ -2083,6 +2213,9 @@ packages: picomatch: optional: true + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -2094,6 +2227,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + finalhandler@1.1.2: + resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} + engines: {node: '>= 0.8'} + find-up-simple@1.0.0: resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} engines: {node: '>=18'} @@ -2328,6 +2465,11 @@ packages: engines: {node: '>=8'} hasBin: true + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-expression@4.0.0: resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} @@ -2351,6 +2493,11 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} @@ -2391,6 +2538,10 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -2539,9 +2690,6 @@ packages: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} - magic-string@0.30.11: - resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} - magic-string@0.30.12: resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} @@ -2638,6 +2786,10 @@ packages: monaco-editor@0.52.0: resolution: {integrity: sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==} + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -2697,6 +2849,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + on-finished@2.3.0: + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} + engines: {node: '>= 0.8'} + on-headers@1.0.2: resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} engines: {node: '>= 0.8'} @@ -2716,6 +2872,10 @@ packages: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} + open@10.1.0: + resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + engines: {node: '>=18'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2757,6 +2917,10 @@ packages: parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2796,6 +2960,12 @@ packages: pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2852,10 +3022,6 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.4.41: - resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.4.48: resolution: {integrity: sha512-GCRK8F6+Dl7xYniR5a4FYbpBzU8XnZVeowqsQFYdcXuSbChgiks7qybSkbvnaeqv0G0B+dd9/jJgH8kkLDQeEA==} engines: {node: ^10 || ^12 || >=14} @@ -3045,11 +3211,6 @@ packages: peerDependencies: rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 - rollup@4.20.0: - resolution: {integrity: sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - rollup@4.25.0: resolution: {integrity: sha512-uVbClXmR6wvx5R1M3Od4utyLUxrmOcEm3pAtMphn73Apq19PDtHpgZoEvqH2YnnaNUuvKmg2DgRd2Sqv+odyqg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -3061,6 +3222,10 @@ packages: rrweb-cssom@0.7.1: resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -3127,6 +3292,10 @@ packages: resolution: {integrity: sha512-tgqwPUMDcNDhuf1Xf6KTUsyeqGdgKMhzaH4PAZZuzguOgTl5uuyeYe/8mWgAr6IBxB5V06uqEf6Dy37gIWDtDg==} hasBin: true + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} @@ -3155,6 +3324,9 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -3180,6 +3352,10 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} @@ -3261,6 +3437,11 @@ packages: resolution: {integrity: sha512-bX655WZI/F7EoTDw9JvQURqAXiPHi8o8+yFxPF2lWYyz1aHnmMRuXWqL6YB6GmeO0o4DIYWHLgGNi/X64T+X4Q==} engines: {node: '>=14.18'} + terser@5.33.0: + resolution: {integrity: sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==} + engines: {node: '>=10'} + hasBin: true + test-exclude@7.0.1: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} @@ -3280,6 +3461,10 @@ packages: tinyexec@0.3.0: resolution: {integrity: sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==} + tinyglobby@0.2.6: + resolution: {integrity: sha512-NbBoFBpqfcgd1tCiO8Lkfdk+xrA7mlLR9zgvZcZWQQwU63XAfUePyd6wZBaU93Hqw347lHnwFzttAkemHzzz4g==} + engines: {node: '>=12.0.0'} + tinypool@1.0.0: resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -3307,6 +3492,10 @@ packages: token-stream@1.0.0: resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==} + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -3381,6 +3570,10 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + update-check@1.5.4: resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==} @@ -3396,6 +3589,10 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} @@ -3403,40 +3600,25 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vite-hyper-config@0.4.0: + resolution: {integrity: sha512-SQSnMt+M8EPLWA4TjU8mvoE/7lPSAnWabN6zEdWOJ2iTrQAKwZ7O6jAsYHUVRPCNgvHAyD0B7s5tluPYvmbAxw==} + engines: {node: '>=18.0.0'} + peerDependencies: + vite: ^4.0.0 || ^5.0.0 + vite-node@2.1.1: resolution: {integrity: sha512-N/mGckI1suG/5wQI35XeR9rsMsPqKXzq1CdUndzVstBj/HvyxxGctwnK6WX43NGt5L3Z5tcRf83g4TITKJhPrA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.4.0: - resolution: {integrity: sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true + vite-plugin-inspect@0.8.7: + resolution: {integrity: sha512-/XXou3MVc13A5O9/2Nd6xczjrUwt7ZyI9h8pTnUMkr5SshLcb0PJUOVq2V+XVkdeU4njsqAtmK87THZuO2coGA==} + engines: {node: '>=14'} peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 + '@nuxt/kit': '*' + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: + '@nuxt/kit': optional: true vite@5.4.8: @@ -3499,6 +3681,25 @@ packages: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue@3.5.13: + resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -3617,6 +3818,8 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 + '@antfu/utils@0.7.10': {} + '@babel/code-frame@7.24.7': dependencies: '@babel/highlight': 7.24.7 @@ -3633,11 +3836,11 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/parser@7.25.3': + '@babel/parser@7.25.6': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.6 - '@babel/types@7.25.2': + '@babel/types@7.25.6': dependencies: '@babel/helper-string-parser': 7.24.8 '@babel/helper-validator-identifier': 7.24.7 @@ -3871,6 +4074,11 @@ snapshots: '@jridgewell/set-array@1.2.1': {} + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.25': @@ -3952,6 +4160,8 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@polka/url@1.0.0-next.25': {} + '@puppeteer/browsers@2.4.0': dependencies: debug: 4.3.6 @@ -4020,27 +4230,15 @@ snapshots: optionalDependencies: rollup: 4.25.0 - '@rollup/rollup-android-arm-eabi@4.20.0': - optional: true - '@rollup/rollup-android-arm-eabi@4.25.0': optional: true - '@rollup/rollup-android-arm64@4.20.0': - optional: true - '@rollup/rollup-android-arm64@4.25.0': optional: true - '@rollup/rollup-darwin-arm64@4.20.0': - optional: true - '@rollup/rollup-darwin-arm64@4.25.0': optional: true - '@rollup/rollup-darwin-x64@4.20.0': - optional: true - '@rollup/rollup-darwin-x64@4.25.0': optional: true @@ -4050,75 +4248,39 @@ snapshots: '@rollup/rollup-freebsd-x64@4.25.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.20.0': - optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.25.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.20.0': - optional: true - '@rollup/rollup-linux-arm-musleabihf@4.25.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-arm64-gnu@4.25.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.20.0': - optional: true - '@rollup/rollup-linux-arm64-musl@4.25.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.25.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-riscv64-gnu@4.25.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-s390x-gnu@4.25.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.20.0': - optional: true - '@rollup/rollup-linux-x64-gnu@4.25.0': optional: true - '@rollup/rollup-linux-x64-musl@4.20.0': - optional: true - '@rollup/rollup-linux-x64-musl@4.25.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.20.0': - optional: true - '@rollup/rollup-win32-arm64-msvc@4.25.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.20.0': - optional: true - '@rollup/rollup-win32-ia32-msvc@4.25.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.20.0': - optional: true - '@rollup/rollup-win32-x64-msvc@4.25.0': optional: true @@ -4176,7 +4338,9 @@ snapshots: '@tootallnate/quickjs-emscripten@0.23.0': {} - '@types/estree@1.0.5': {} + '@types/connect@3.4.38': + dependencies: + '@types/node': 22.8.7 '@types/estree@1.0.6': {} @@ -4200,6 +4364,8 @@ snapshots: '@types/trusted-types@2.0.7': {} + '@types/web-bluetooth@0.0.20': {} + '@types/yauzl@2.10.3': dependencies: '@types/node': 22.8.7 @@ -4324,12 +4490,22 @@ snapshots: '@typescript-eslint/types': 8.12.2 eslint-visitor-keys: 3.4.3 - '@vitejs/plugin-vue@5.1.2(vite@5.4.0(@types/node@22.8.7)(sass@1.80.6))(vue@packages+vue)': + '@vitejs/plugin-vue@5.1.4(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)': + dependencies: + vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) + vue: link:packages/vue + + '@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@481bcd4(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@packages+vue)': dependencies: - vite: 5.4.0(@types/node@22.8.7)(sass@1.80.6) + vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) vue: link:packages/vue - '@vitest/coverage-v8@2.1.1(vitest@2.1.1(@types/node@22.8.7)(jsdom@25.0.0)(sass@1.80.6))': + '@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@e3c5ce5(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))(vue@3.5.13(typescript@5.6.2))': + dependencies: + vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) + vue: 3.5.13(typescript@5.6.2) + + '@vitest/coverage-v8@2.1.1(vitest@2.1.1)': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -4343,15 +4519,15 @@ snapshots: std-env: 3.7.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.1.1(@types/node@22.8.7)(jsdom@25.0.0)(sass@1.80.6) + vitest: 2.1.1(@types/node@22.8.7)(@vitest/ui@2.1.1)(jsdom@25.0.0)(sass@1.80.6)(terser@5.33.0) transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.1.6(@typescript-eslint/utils@8.12.2(eslint@9.14.0)(typescript@5.6.2))(eslint@9.14.0)(typescript@5.6.2)(vitest@2.1.1(@types/node@22.8.7)(jsdom@25.0.0)(sass@1.80.6))': + '@vitest/eslint-plugin@1.1.6(@typescript-eslint/utils@8.12.2(eslint@9.14.0)(typescript@5.6.2))(eslint@9.14.0)(typescript@5.6.2)(vitest@2.1.1)': dependencies: '@typescript-eslint/utils': 8.12.2(eslint@9.14.0)(typescript@5.6.2) eslint: 9.14.0 - vitest: 2.1.1(@types/node@22.8.7)(jsdom@25.0.0)(sass@1.80.6) + vitest: 2.1.1(@types/node@22.8.7)(@vitest/ui@2.1.1)(jsdom@25.0.0)(sass@1.80.6)(terser@5.33.0) optionalDependencies: typescript: 5.6.2 @@ -4362,13 +4538,13 @@ snapshots: chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6))': + '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0))': dependencies: '@vitest/spy': 2.1.1 estree-walker: 3.0.3 magic-string: 0.30.12 optionalDependencies: - vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6) + vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) '@vitest/pretty-format@2.1.1': dependencies: @@ -4389,16 +4565,100 @@ snapshots: dependencies: tinyspy: 3.0.0 + '@vitest/ui@2.1.1(vitest@2.1.1)': + dependencies: + '@vitest/utils': 2.1.1 + fflate: 0.8.2 + flatted: 3.3.1 + pathe: 1.1.2 + sirv: 2.0.4 + tinyglobby: 0.2.6 + tinyrainbow: 1.2.0 + vitest: 2.1.1(@types/node@22.8.7)(@vitest/ui@2.1.1)(jsdom@25.0.0)(sass@1.80.6)(terser@5.33.0) + '@vitest/utils@2.1.1': dependencies: '@vitest/pretty-format': 2.1.1 loupe: 3.1.1 tinyrainbow: 1.2.0 + '@vue/compiler-core@3.5.13': + dependencies: + '@babel/parser': 7.25.6 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.13': + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-sfc@3.5.13': + dependencies: + '@babel/parser': 7.25.6 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + estree-walker: 2.0.2 + magic-string: 0.30.12 + postcss: 8.4.48 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.13': + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 + '@vue/consolidate@1.0.0': {} + '@vue/reactivity@3.5.13': + dependencies: + '@vue/shared': 3.5.13 + '@vue/repl@4.4.2': {} + '@vue/runtime-core@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/runtime-dom@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/runtime-core': 3.5.13 + '@vue/shared': 3.5.13 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.6.2))': + dependencies: + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + vue: 3.5.13(typescript@5.6.2) + + '@vue/shared@3.5.13': {} + + '@vueuse/core@11.1.0(vue@packages+vue)': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 11.1.0 + '@vueuse/shared': 11.1.0(vue@packages+vue) + vue-demi: 0.14.10(vue@packages+vue) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@11.1.0': {} + + '@vueuse/shared@11.1.0(vue@packages+vue)': + dependencies: + vue-demi: 0.14.10(vue@packages+vue) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + '@zeit/schemas@2.36.0': {} accepts@1.3.8: @@ -4484,7 +4744,7 @@ snapshots: babel-walk@3.0.0-canary-5: dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.6 balanced-match@1.0.2: {} @@ -4541,11 +4801,17 @@ snapshots: buffer-crc32@0.2.13: {} + buffer-from@1.1.2: {} + buffer@5.7.1: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + bytes@3.0.0: {} cac@6.7.14: {} @@ -4649,6 +4915,8 @@ snapshots: commander@12.1.0: {} + commander@2.20.3: {} + commondir@1.0.1: {} compare-func@2.0.0: @@ -4674,10 +4942,19 @@ snapshots: concat-map@0.0.1: {} + connect@3.7.0: + dependencies: + debug: 2.6.9 + finalhandler: 1.1.2 + parseurl: 1.3.3 + utils-merge: 1.0.1 + transitivePeerDependencies: + - supports-color + constantinople@4.0.1: dependencies: - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 + '@babel/parser': 7.25.6 + '@babel/types': 7.25.6 content-disposition@0.5.2: {} @@ -4805,6 +5082,10 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.3.7: + dependencies: + ms: 2.1.3 + decimal.js@10.4.3: {} deep-eql@5.0.2: {} @@ -4815,12 +5096,21 @@ snapshots: deepmerge@4.3.1: {} + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + define-data-property@1.1.4: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 gopd: 1.0.1 + define-lazy-prop@3.0.0: {} + degenerator@5.0.1: dependencies: ast-types: 0.13.4 @@ -4846,12 +5136,16 @@ snapshots: eastasianwidth@0.2.0: {} + ee-first@1.1.1: {} + emoji-regex@10.3.0: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} + encodeurl@1.0.2: {} + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -4871,6 +5165,8 @@ snapshots: dependencies: is-arrayish: 0.2.1 + error-stack-parser-es@0.1.5: {} + es-define-property@1.0.0: dependencies: get-intrinsic: 1.2.4 @@ -4940,6 +5236,8 @@ snapshots: escalade@3.1.2: {} + escape-html@1.0.3: {} + escape-string-regexp@1.0.5: {} escape-string-regexp@4.0.0: {} @@ -5112,10 +5410,16 @@ snapshots: dependencies: pend: 1.2.0 + fdir@6.3.0(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + fdir@6.4.0(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 + fflate@0.8.2: {} + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -5126,6 +5430,18 @@ snapshots: dependencies: to-regex-range: 5.0.1 + finalhandler@1.1.2: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.3.0 + parseurl: 1.3.3 + statuses: 1.5.0 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + find-up-simple@1.0.0: {} find-up@5.0.0: @@ -5356,6 +5672,8 @@ snapshots: is-docker@2.2.1: {} + is-docker@3.0.0: {} + is-expression@4.0.0: dependencies: acorn: 7.4.1 @@ -5375,6 +5693,10 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-module@1.0.0: {} is-number@7.0.0: {} @@ -5404,6 +5726,10 @@ snapshots: dependencies: is-docker: 2.2.1 + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + isarray@1.0.0: {} isexe@2.0.0: {} @@ -5584,18 +5910,14 @@ snapshots: lru-cache@7.18.3: {} - magic-string@0.30.11: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - magic-string@0.30.12: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 magicast@0.3.4: dependencies: - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 + '@babel/parser': 7.25.6 + '@babel/types': 7.25.6 source-map-js: 1.2.1 make-dir@4.0.0: @@ -5663,6 +5985,8 @@ snapshots: monaco-editor@0.52.0: {} + mrmime@2.0.0: {} + ms@2.0.0: {} ms@2.1.2: {} @@ -5713,6 +6037,10 @@ snapshots: object-assign@4.1.1: {} + on-finished@2.3.0: + dependencies: + ee-first: 1.1.1 + on-headers@1.0.2: {} once@1.4.0: @@ -5731,6 +6059,13 @@ snapshots: dependencies: mimic-function: 5.0.1 + open@10.1.0: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -5791,6 +6126,8 @@ snapshots: dependencies: entities: 4.5.0 + parseurl@1.3.3: {} + path-exists@4.0.0: {} path-is-inside@1.0.2: {} @@ -5819,6 +6156,10 @@ snapshots: pend@1.2.0: {} + perfect-debounce@1.0.0: {} + + picocolors@1.1.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -5872,12 +6213,6 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.4.41: - dependencies: - nanoid: 3.3.7 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.4.48: dependencies: nanoid: 3.3.7 @@ -6125,28 +6460,6 @@ snapshots: '@rollup/plugin-inject': 5.0.5(rollup@4.25.0) rollup: 4.25.0 - rollup@4.20.0: - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.20.0 - '@rollup/rollup-android-arm64': 4.20.0 - '@rollup/rollup-darwin-arm64': 4.20.0 - '@rollup/rollup-darwin-x64': 4.20.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.20.0 - '@rollup/rollup-linux-arm-musleabihf': 4.20.0 - '@rollup/rollup-linux-arm64-gnu': 4.20.0 - '@rollup/rollup-linux-arm64-musl': 4.20.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.20.0 - '@rollup/rollup-linux-riscv64-gnu': 4.20.0 - '@rollup/rollup-linux-s390x-gnu': 4.20.0 - '@rollup/rollup-linux-x64-gnu': 4.20.0 - '@rollup/rollup-linux-x64-musl': 4.20.0 - '@rollup/rollup-win32-arm64-msvc': 4.20.0 - '@rollup/rollup-win32-ia32-msvc': 4.20.0 - '@rollup/rollup-win32-x64-msvc': 4.20.0 - fsevents: 2.3.3 - rollup@4.25.0: dependencies: '@types/estree': 1.0.6 @@ -6175,6 +6488,8 @@ snapshots: rrweb-cssom@0.7.1: {} + run-applescript@7.0.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -6252,6 +6567,12 @@ snapshots: simple-git-hooks@2.11.1: {} + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.25 + mrmime: 2.0.0 + totalist: 3.0.1 + slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 @@ -6281,6 +6602,11 @@ snapshots: source-map-js@1.2.1: {} + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + source-map@0.6.1: {} spdx-correct@3.2.0: @@ -6303,6 +6629,8 @@ snapshots: stackback@0.0.2: {} + statuses@1.5.0: {} + std-env@3.7.0: {} streamx@2.18.0: @@ -6387,6 +6715,13 @@ snapshots: dependencies: temp-dir: 3.0.0 + terser@5.33.0: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.14.0 + commander: 2.20.3 + source-map-support: 0.5.21 + test-exclude@7.0.1: dependencies: '@istanbuljs/schema': 0.1.3 @@ -6405,6 +6740,11 @@ snapshots: tinyexec@0.3.0: {} + tinyglobby@0.2.6: + dependencies: + fdir: 6.3.0(picomatch@4.0.2) + picomatch: 4.0.2 + tinypool@1.0.0: {} tinyrainbow@1.2.0: {} @@ -6421,6 +6761,8 @@ snapshots: token-stream@1.0.0: {} + totalist@3.0.1: {} + tough-cookie@4.1.4: dependencies: psl: 1.9.0 @@ -6479,6 +6821,8 @@ snapshots: universalify@2.0.1: {} + unpipe@1.0.0: {} + update-check@1.5.4: dependencies: registry-auth-token: 3.3.2 @@ -6497,6 +6841,8 @@ snapshots: util-deprecate@1.0.2: {} + utils-merge@1.0.1: {} + validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 @@ -6504,12 +6850,29 @@ snapshots: vary@1.1.2: {} - vite-node@2.1.1(@types/node@22.8.7)(sass@1.80.6): + vite-hyper-config@0.4.0(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)): + dependencies: + cac: 6.7.14 + picocolors: 1.1.0 + vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) + vite-node: 2.1.1(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite-node@2.1.1(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0): dependencies: cac: 6.7.14 debug: 4.3.6 pathe: 1.1.2 - vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6) + vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) transitivePeerDependencies: - '@types/node' - less @@ -6521,17 +6884,23 @@ snapshots: - supports-color - terser - vite@5.4.0(@types/node@22.8.7)(sass@1.80.6): + vite-plugin-inspect@0.8.7(rollup@4.25.0)(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)): dependencies: - esbuild: 0.21.5 - postcss: 8.4.41 - rollup: 4.20.0 - optionalDependencies: - '@types/node': 22.8.7 - fsevents: 2.3.3 - sass: 1.80.6 + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.1.0(rollup@4.25.0) + debug: 4.3.7 + error-stack-parser-es: 0.1.5 + fs-extra: 11.2.0 + open: 10.1.0 + perfect-debounce: 1.0.0 + picocolors: 1.1.0 + sirv: 2.0.4 + vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) + transitivePeerDependencies: + - rollup + - supports-color - vite@5.4.8(@types/node@22.8.7)(sass@1.80.6): + vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0): dependencies: esbuild: 0.21.5 postcss: 8.4.48 @@ -6540,11 +6909,12 @@ snapshots: '@types/node': 22.8.7 fsevents: 2.3.3 sass: 1.80.6 + terser: 5.33.0 - vitest@2.1.1(@types/node@22.8.7)(jsdom@25.0.0)(sass@1.80.6): + vitest@2.1.1(@types/node@22.8.7)(@vitest/ui@2.1.1)(jsdom@25.0.0)(sass@1.80.6)(terser@5.33.0): dependencies: '@vitest/expect': 2.1.1 - '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)) + '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(vite@5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0)) '@vitest/pretty-format': 2.1.1 '@vitest/runner': 2.1.1 '@vitest/snapshot': 2.1.1 @@ -6559,11 +6929,12 @@ snapshots: tinyexec: 0.3.0 tinypool: 1.0.0 tinyrainbow: 1.2.0 - vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6) - vite-node: 2.1.1(@types/node@22.8.7)(sass@1.80.6) + vite: 5.4.8(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) + vite-node: 2.1.1(@types/node@22.8.7)(sass@1.80.6)(terser@5.33.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.8.7 + '@vitest/ui': 2.1.1(vitest@2.1.1) jsdom: 25.0.0 transitivePeerDependencies: - less @@ -6578,6 +6949,20 @@ snapshots: void-elements@3.1.0: {} + vue-demi@0.14.10(vue@packages+vue): + dependencies: + vue: link:packages/vue + + vue@3.5.13(typescript@5.6.2): + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-sfc': 3.5.13 + '@vue/runtime-dom': 3.5.13 + '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.6.2)) + '@vue/shared': 3.5.13 + optionalDependencies: + typescript: 5.6.2 + w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 @@ -6614,8 +6999,8 @@ snapshots: with@7.0.2: dependencies: - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 + '@babel/parser': 7.25.6 + '@babel/types': 7.25.6 assert-never: 1.3.0 babel-walk: 3.0.0-canary-5 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 23270954bb3..d01dbb0480c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,6 +1,8 @@ packages: - 'packages/*' - 'packages-private/*' + - playground + - benchmark catalog: '@babel/parser': ^7.25.3 diff --git a/rollup.config.js b/rollup.config.js index da7de554b64..cc71782bf30 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -15,13 +15,14 @@ import alias from '@rollup/plugin-alias' import { entries } from './scripts/aliases.js' import { inlineEnums } from './scripts/inline-enums.js' import { minify as minifySwc } from '@swc/core' +import { trimVaporExportsPlugin } from './scripts/trim-vapor-exports.js' /** * @template T * @template {keyof T} K * @typedef { Omit & Required> } MarkRequired */ -/** @typedef {'cjs' | 'esm-bundler' | 'global' | 'global-runtime' | 'esm-browser' | 'esm-bundler-runtime' | 'esm-browser-runtime'} PackageFormat */ +/** @typedef {'cjs' | 'esm-bundler' | 'global' | 'global-runtime' | 'esm-browser' | 'esm-bundler-runtime' | 'esm-browser-runtime' | 'vapor'} PackageFormat */ /** @typedef {MarkRequired} OutputOptions */ if (!process.env.TARGET) { @@ -85,13 +86,19 @@ const outputConfigs = { file: resolve(`dist/${name}.runtime.global.js`), format: 'iife', }, + // The vapor format is a esm-browser + runtime only build that is meant for + // the SFC playground only. + vapor: { + file: resolve(`dist/${name}.runtime-with-vapor.esm-browser.js`), + format: 'es', + }, } /** @type {ReadonlyArray} */ const defaultFormats = ['esm-bundler', 'cjs'] /** @type {ReadonlyArray} */ const inlineFormats = /** @type {any} */ ( - process.env.FORMATS && process.env.FORMATS.split(',') + process.env.FORMATS && process.env.FORMATS.split('+') ) /** @type {ReadonlyArray} */ const packageFormats = inlineFormats || packageOptions.formats || defaultFormats @@ -107,7 +114,7 @@ if (process.env.NODE_ENV === 'production') { if (format === 'cjs') { packageConfigs.push(createProductionConfig(format)) } - if (/^(global|esm-browser)(-runtime)?/.test(format)) { + if (format === 'vapor' || /^(global|esm-browser)(-runtime)?/.test(format)) { packageConfigs.push(createMinifiedConfig(format)) } }) @@ -131,12 +138,14 @@ function createConfig(format, output, plugins = []) { const isProductionBuild = process.env.__DEV__ === 'false' || /\.prod\.js$/.test(output.file) const isBundlerESMBuild = /esm-bundler/.test(format) - const isBrowserESMBuild = /esm-browser/.test(format) + const isBrowserESMBuild = /esm-browser/.test(format) || format === 'vapor' const isServerRenderer = name === 'server-renderer' const isCJSBuild = format === 'cjs' const isGlobalBuild = /global/.test(format) const isCompatPackage = - pkg.name === '@vue/compat' || pkg.name === '@vue/compat-canary' + pkg.name === '@vue/compat' || + pkg.name === '@vue/compat-canary' || + pkg.name === '@vue-vapor/compat' const isCompatBuild = !!packageOptions.compat const isBrowserBuild = (isGlobalBuild || isBrowserESMBuild || isBundlerESMBuild) && @@ -157,15 +166,56 @@ function createConfig(format, output, plugins = []) { output.name = packageOptions.name } - let entryFile = /runtime$/.test(format) ? `src/runtime.ts` : `src/index.ts` + let entryFile = + pkg.name === 'vue' && + (format === 'vapor' || format.startsWith('esm-bundler')) + ? 'runtime-with-vapor.ts' + : /\bruntime\b/.test(format) + ? `runtime.ts` + : `index.ts` // the compat build needs both default AND named exports. This will cause // Rollup to complain for non-ESM targets, so we use separate entries for // esm vs. non-esm builds. if (isCompatPackage && (isBrowserESMBuild || isBundlerESMBuild)) { - entryFile = /runtime$/.test(format) - ? `src/esm-runtime.ts` - : `src/esm-index.ts` + entryFile = `esm-${entryFile}` + } + entryFile = 'src/' + entryFile + + return { + input: resolve(entryFile), + // Global and Browser ESM builds inlines everything so that they can be + // used alone. + external: resolveExternal(), + plugins: [ + ...trimVaporExportsPlugin(format, pkg.name), + json({ + namedExports: false, + }), + alias({ + entries, + }), + enumPlugin, + ...resolveReplace(), + esbuild({ + tsconfig: path.resolve(__dirname, 'tsconfig.json'), + sourceMap: output.sourcemap, + minify: false, + target: isServerRenderer || isCJSBuild ? 'es2019' : 'es2016', + define: resolveDefine(), + }), + ...resolveNodePlugins(), + ...plugins, + ], + output, + onwarn(msg, warn) { + if (msg.code !== 'CIRCULAR_DEPENDENCY') { + warn(msg) + } + }, + treeshake: { + moduleSideEffects: false, + }, } function resolveDefine() { @@ -184,6 +234,7 @@ function createConfig(format, output, plugins = []) { __CJS__: String(isCJSBuild), // need SSR-specific branches? __SSR__: String(!isGlobalBuild), + __BENCHMARK__: process.env.BENCHMARK || 'false', // 2.x compat build __COMPAT__: String(isCompatBuild), @@ -290,7 +341,8 @@ function createConfig(format, output, plugins = []) { let cjsIgnores = [] if ( pkg.name === '@vue/compiler-sfc' || - pkg.name === '@vue/compiler-sfc-canary' + pkg.name === '@vue/compiler-sfc-canary' || + pkg.name === '@vue-vapor/compiler-sfc' ) { cjsIgnores = [ ...Object.keys(consolidatePkg.devDependencies), @@ -319,47 +371,12 @@ function createConfig(format, output, plugins = []) { return nodePlugins } - - return { - input: resolve(entryFile), - // Global and Browser ESM builds inlines everything so that they can be - // used alone. - external: resolveExternal(), - plugins: [ - json({ - namedExports: false, - }), - alias({ - entries, - }), - enumPlugin, - ...resolveReplace(), - esbuild({ - tsconfig: path.resolve(__dirname, 'tsconfig.json'), - sourceMap: output.sourcemap, - minify: false, - target: isServerRenderer || isCJSBuild ? 'es2019' : 'es2016', - define: resolveDefine(), - }), - ...resolveNodePlugins(), - ...plugins, - ], - output, - onwarn: (msg, warn) => { - if (msg.code !== 'CIRCULAR_DEPENDENCY') { - warn(msg) - } - }, - treeshake: { - moduleSideEffects: false, - }, - } } function createProductionConfig(/** @type {PackageFormat} */ format) { return createConfig(format, { + ...outputConfigs[format], file: resolve(`dist/${name}.${format}.prod.js`), - format: outputConfigs[format].format, }) } @@ -367,8 +384,8 @@ function createMinifiedConfig(/** @type {PackageFormat} */ format) { return createConfig( format, { + ...outputConfigs[format], file: outputConfigs[format].file.replace(/\.js$/, '.prod.js'), - format: outputConfigs[format].format, }, [ { diff --git a/scripts/build.js b/scripts/build.js index 4a0aef64543..7af93db4043 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -5,14 +5,17 @@ Produces production builds and stitches together d.ts files. To specify the package to build, simply pass its name and the desired build formats to output (defaults to `buildOptions.formats` specified in that package, -or "esm,cjs"): +or ["esm-bundler", "cjs"]): ``` # name supports fuzzy match. will build all packages with name containing "dom": nr build dom # specify the format to output -nr build core --formats cjs +nr build vue -f cjs + +# to specify multiple formats, separate with "+": +nr build vue -f esm-bundler+esm-browser ``` */ diff --git a/scripts/dev.js b/scripts/dev.js index fb4d3873e8b..06bf7de93ed 100644 --- a/scripts/dev.js +++ b/scripts/dev.js @@ -49,9 +49,12 @@ const outputFormat = format.startsWith('global') ? 'cjs' : 'esm' -const postfix = format.endsWith('-runtime') - ? `runtime.${format.replace(/-runtime$/, '')}` - : format +const postfix = + format === 'vapor' + ? 'runtime-with-vapor.esm-browser' + : format.endsWith('-runtime') + ? `runtime.${format.replace(/-runtime$/, '')}` + : format const privatePackages = fs.readdirSync('packages-private') @@ -127,9 +130,16 @@ for (const target of targets) { plugins.push(polyfillNode()) } + const entry = + format === 'vapor' + ? 'runtime-with-vapor.ts' + : format.endsWith('-runtime') + ? 'runtime.ts' + : 'index.ts' + esbuild .context({ - entryPoints: [resolve(__dirname, `${pkgBasePath}/src/index.ts`)], + entryPoints: [resolve(__dirname, `${pkgBasePath}/src/${entry}`)], outfile, bundle: true, external, @@ -151,6 +161,7 @@ for (const target of targets) { __ESM_BROWSER__: String(format.includes('esm-browser')), __CJS__: String(format === 'cjs'), __SSR__: String(format !== 'global'), + __BENCHMARK__: process.env.BENCHMARK || 'false', __COMPAT__: String(target === 'vue-compat'), __FEATURE_SUSPENSE__: `true`, __FEATURE_OPTIONS_API__: `true`, diff --git a/scripts/inline-enums.js b/scripts/inline-enums.js index b1baaa6c5c3..4e582e25185 100644 --- a/scripts/inline-enums.js +++ b/scripts/inline-enums.js @@ -198,7 +198,9 @@ export function scanEnums() { } // 3. save cache - if (!existsSync('temp')) mkdirSync('temp') + try { + mkdirSync('temp') + } catch {} /** @type {EnumData} */ const enumData = { diff --git a/scripts/pre-dev-sfc.js b/scripts/prepare-cjs.js similarity index 95% rename from scripts/pre-dev-sfc.js rename to scripts/prepare-cjs.js index b28705f3464..3e427e2b77f 100644 --- a/scripts/pre-dev-sfc.js +++ b/scripts/prepare-cjs.js @@ -6,6 +6,7 @@ const packagesToCheck = [ 'compiler-core', 'compiler-dom', 'compiler-ssr', + 'compiler-vapor', 'shared', ] diff --git a/scripts/release.js b/scripts/release.js index cd287dfc12b..9872a1f3f37 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -6,7 +6,7 @@ import semver from 'semver' import enquirer from 'enquirer' import { createRequire } from 'node:module' import { fileURLToPath } from 'node:url' -import { exec } from './utils.js' +import { exec, getSha } from './utils.js' import { parseArgs } from 'node:util' /** @@ -425,10 +425,6 @@ async function isInSyncWithRemote() { } } -async function getSha() { - return (await exec('git', ['rev-parse', 'HEAD'])).stdout -} - async function getBranch() { return (await exec('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout } diff --git a/scripts/trim-vapor-exports.js b/scripts/trim-vapor-exports.js new file mode 100644 index 00000000000..672192fc6c4 --- /dev/null +++ b/scripts/trim-vapor-exports.js @@ -0,0 +1,36 @@ +// @ts-check + +/** + * runtime-core exports a number of internal helpers that are only used by + * runtime-vapor, which should be only preserved in vapor / esm-bundler builds. + * This plugin should be included as the first plugin for all other formats + * other than vapor / esm-bundler. + * + * @param {string} format + * @param {string} pkgName + * @returns {import('rollup').Plugin[]} + */ +export function trimVaporExportsPlugin(format, pkgName) { + if ( + format === 'vapor' || + format.startsWith('esm-bundler') || + pkgName === '@vue/runtime-vapor' + ) { + return [] + } else { + return [ + { + name: 'trim-vapor-exports', + transform(code, id) { + if ( + id.endsWith('runtime-core/src/index.ts') || + id.endsWith('runtime-dom/src/index.ts') + ) { + const index = code.lastIndexOf('// VAPOR ---') + return code.slice(0, index) + } + }, + }, + ] + } +} diff --git a/scripts/usage-size.js b/scripts/usage-size.js index c68e3703b91..3d01fc8283e 100644 --- a/scripts/usage-size.js +++ b/scripts/usage-size.js @@ -22,12 +22,14 @@ const { }) const sizeDir = path.resolve('temp/size') -const entry = path.resolve('./packages/vue/dist/vue.runtime.esm-bundler.js') +const vue = path.resolve('./packages/vue/dist/vue.runtime.esm-bundler.js') +const vapor = path.resolve('./packages/vue-vapor/dist/vue-vapor.esm-bundler.js') /** * @typedef {Object} Preset * @property {string} name - The name of the preset - * @property {string[]} imports - The imports that are part of this preset + * @property {'*' | string[]} imports - The imports that are part of this preset + * @property {string} from - The path to the entry file * @property {Record} [replace] */ @@ -37,10 +39,12 @@ const presets = [ name: 'createApp (CAPI only)', imports: ['createApp'], replace: { __VUE_OPTIONS_API__: 'false' }, + from: vue, }, - { name: 'createApp', imports: ['createApp'] }, - { name: 'createSSRApp', imports: ['createSSRApp'] }, - { name: 'defineCustomElement', imports: ['defineCustomElement'] }, + { name: 'createApp', imports: ['createApp'], from: vue }, + { name: 'createVaporApp', imports: ['createVaporApp'], from: vapor }, + { name: 'createSSRApp', imports: ['createSSRApp'], from: vue }, + { name: 'defineCustomElement', imports: ['defineCustomElement'], from: vue }, { name: 'overall', imports: [ @@ -51,6 +55,7 @@ const presets = [ 'KeepAlive', 'Suspense', ], + from: vue, }, ] @@ -93,8 +98,11 @@ async function main() { */ async function generateBundle(preset) { const id = 'virtual:entry' - const content = `export { ${preset.imports.join(', ')} } from '${entry}'` - + const exportSpecifiers = + preset.imports === '*' + ? `* as ${preset.name}` + : `{ ${preset.imports.join(', ')} }` + const content = `export ${exportSpecifiers} from '${preset.from}'` const result = await rollup({ input: id, plugins: [ diff --git a/scripts/utils.js b/scripts/utils.js index 3c92bf7bafb..cad185a4bc2 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -3,19 +3,22 @@ import fs from 'node:fs' import pico from 'picocolors' import { createRequire } from 'node:module' import { spawn } from 'node:child_process' +import path from 'node:path' const require = createRequire(import.meta.url) +const packagesPath = path.resolve(import.meta.dirname, '../packages') export const targets = fs - .readdirSync('packages') + .readdirSync(packagesPath) .filter(f => { + const folder = path.resolve(packagesPath, f) if ( - !fs.statSync(`packages/${f}`).isDirectory() || - !fs.existsSync(`packages/${f}/package.json`) + !fs.statSync(folder).isDirectory() || + !fs.existsSync(`${folder}/package.json`) ) { return false } - const pkg = require(`../packages/${f}/package.json`) + const pkg = require(`${folder}/package.json`) if (pkg.private && !pkg.buildOptions) { return false } @@ -32,6 +35,10 @@ export function fuzzyMatchTarget(partialTargets, includeAllMatching) { /** @type {Array} */ const matched = [] partialTargets.forEach(partialTarget => { + if (!includeAllMatching && targets.includes(partialTarget)) { + matched.push(partialTarget) + return + } for (const target of targets) { if (target.match(partialTarget)) { matched.push(target) @@ -60,6 +67,7 @@ export function fuzzyMatchTarget(partialTargets, includeAllMatching) { * @param {string} command * @param {ReadonlyArray} args * @param {object} [options] + * @returns {Promise<{ ok: boolean, code: number | null, stderr: string, stdout: string }>} */ export async function exec(command, args, options) { return new Promise((resolve, reject) => { @@ -112,3 +120,12 @@ export async function exec(command, args, options) { }) }) } + +/** + * @param {boolean=} short + */ +export async function getSha(short) { + return ( + await exec('git', ['rev-parse', ...(short ? ['--short'] : []), 'HEAD']) + ).stdout +} diff --git a/tsconfig.build.json b/tsconfig.build.json index fc36b251d51..caefe028003 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -11,6 +11,7 @@ "packages/global.d.ts", "packages/vue/src", "packages/vue-compat/src", + "packages/vue-vapor/src", "packages/compiler-core/src", "packages/compiler-dom/src", "packages/runtime-core/src", diff --git a/tsconfig.json b/tsconfig.json index 9896083cf14..8973145f6f3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,7 +24,7 @@ "paths": { "@vue/compat": ["packages/vue-compat/src"], "@vue/*": ["packages/*/src"], - "vue": ["packages/vue/src"] + "vue": ["packages/vue/src/runtime-with-vapor.ts"] }, "isolatedDeclarations": true, "composite": true diff --git a/vitest.config.ts b/vitest.config.ts index 67db1d8506c..4d7285f7616 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -12,6 +12,7 @@ export default defineConfig({ __ESM_BROWSER__: false, __CJS__: true, __SSR__: true, + __BENCHMARK__: false, __FEATURE_OPTIONS_API__: true, __FEATURE_SUSPENSE__: true, __FEATURE_PROD_DEVTOOLS__: false, @@ -26,7 +27,7 @@ export default defineConfig({ pool: 'threads', setupFiles: 'scripts/setup-vitest.ts', environmentMatchGlobs: [ - ['packages/{vue,vue-compat,runtime-dom}/**', 'jsdom'], + ['packages/{vue,vue-compat,runtime-dom,runtime-vapor}/**', 'jsdom'], ], sequence: { hooks: 'list', diff --git a/vitest.e2e.config.ts b/vitest.e2e.config.ts index 622bda0bd57..e50d89360f7 100644 --- a/vitest.e2e.config.ts +++ b/vitest.e2e.config.ts @@ -9,6 +9,9 @@ export default mergeConfig(config, { singleThread: !!process.env.CI, }, }, - include: ['packages/vue/__tests__/e2e/*.spec.ts'], + include: [ + 'packages/vue/__tests__/e2e/*.spec.ts', + 'packages/vue-vapor/__tests__/e2e/*.spec.ts', + ], }, })