diff --git a/build.mjs b/build.mjs index e7e88ad56d6..7e76e821c56 100644 --- a/build.mjs +++ b/build.mjs @@ -1,6 +1,6 @@ /** - * Build helper scripts - * Usage: node build.mjs [options] -- [rollup options] + * Build helper script using esbuild for JS targets and Rollup for types. + * Usage: node build.mjs [options] * * Options: * target[:][:][:] - Specify the target @@ -9,37 +9,177 @@ * - bundleState (unbundled, bundled) * Example: target:esm:release:bundled * - * treemap - Enable treemap build visualization (release only). - * treenet - Enable treenet build visualization (release only). - * treesun - Enable treesun build visualization (release only). - * treeflame - Enable treeflame build visualization (release only). + * -w / --watch - Enable watch mode (rebuilds on file changes). */ -import { execSync } from 'child_process'; +import fs from 'fs'; +import { buildTarget, OUT_PREFIX } from './utils/esbuild-build-target.mjs'; +import { version, revision } from './utils/rollup-version-revision.mjs'; +import { buildTypesOption } from './utils/rollup-build-target.mjs'; + +const CYAN_OUT = '\x1b[36m'; +const BLUE_OUT = '\x1b[34m'; +const GREEN_OUT = '\x1b[32m'; +const RED_OUT = '\x1b[31m'; +const BOLD_OUT = '\x1b[1m'; +const REGULAR_OUT = '\x1b[22m'; +const RESET_OUT = '\x1b[0m'; + +const BUILD_TYPES = ['release', 'debug', 'profiler', 'min']; +const MODULE_FORMAT = ['umd', 'esm']; +const BUNDLE_STATES = ['unbundled', 'bundled']; const args = process.argv.slice(2); -const ENV_START_MATCHES = [ - 'target', - 'treemap', - 'treenet', - 'treesun', - 'treeflame' -]; - -const env = []; -for (let i = 0; i < args.length; i++) { - if (ENV_START_MATCHES.some(match => args[i].startsWith(match)) && args[i - 1] !== '--environment') { - env.push(`--environment ${args[i]}`); - args.splice(i, 1); - i--; - continue; +// Extract target and flags +let envTarget = null; +let watchMode = false; +for (const arg of args) { + if (arg.startsWith('target')) { + const parts = arg.split(':'); + envTarget = parts.slice(1).join(':').toLowerCase() || null; + } + if (arg === '-w' || arg === '--watch') { + watchMode = true; + } +} + +const title = [ + 'Building PlayCanvas Engine', + `version ${BOLD_OUT}v${version}${REGULAR_OUT}`, + `revision ${BOLD_OUT}${revision}${REGULAR_OUT}`, + `target ${BOLD_OUT}${envTarget ?? 'all'}${REGULAR_OUT}` +].join('\n'); +console.log(`${BLUE_OUT}${title}${RESET_OUT}`); + +if (envTarget === null && fs.existsSync('build')) { + fs.rmSync('build', { recursive: true }); +} + +function includeBuild(buildType, moduleFormat, bundleState) { + return envTarget === null || + envTarget === buildType || + envTarget === moduleFormat || + envTarget === bundleState || + envTarget === `${moduleFormat}:${buildType}` || + envTarget === `${moduleFormat}:${bundleState}` || + envTarget === `${buildType}:${bundleState}` || + envTarget === `${moduleFormat}:${buildType}:${bundleState}`; +} + +// Collect JS build targets +const jsTargets = []; +BUILD_TYPES.forEach((buildType) => { + MODULE_FORMAT.forEach((moduleFormat) => { + BUNDLE_STATES.forEach((bundleState) => { + if (bundleState === 'unbundled' && moduleFormat === 'umd') return; + if (bundleState === 'unbundled' && buildType === 'min') return; + if (!includeBuild(buildType, moduleFormat, bundleState)) return; + + jsTargets.push({ moduleFormat, buildType, bundleState }); + }); + }); +}); + +const buildTypes = envTarget === null || envTarget === 'types'; + +if (!jsTargets.length && !buildTypes) { + console.error(`${RED_OUT}${BOLD_OUT}No targets found${RESET_OUT}`); + process.exit(1); +} + +/** + * Get the output path description for a build target (matches Rollup's display). + * + * @param {object} target - The build target. + * @returns {string} The output path. + */ +function getOutputPath(target) { + const prefix = OUT_PREFIX[target.buildType]; + const isUMD = target.moduleFormat === 'umd'; + const bundled = isUMD || target.buildType === 'min' || target.bundleState === 'bundled'; + if (bundled) { + return `build/${prefix}${isUMD ? '.js' : '.mjs'}`; } + return `build/${prefix}/`; +} + +/** + * Build all JS targets using esbuild. + */ +async function buildAllJS() { + await Promise.all(jsTargets.map(async (target) => { + const output = getOutputPath(target); + console.log(`${CYAN_OUT}${BOLD_OUT}src/index.js${REGULAR_OUT} \u2192 ${BOLD_OUT}${output}${REGULAR_OUT}...${RESET_OUT}`); + const buildStart = performance.now(); + try { + await buildTarget(target); + const elapsed = ((performance.now() - buildStart) / 1000).toFixed(1); + console.log(`${GREEN_OUT}created ${BOLD_OUT}${output}${REGULAR_OUT} in ${BOLD_OUT}${elapsed}s${REGULAR_OUT}${RESET_OUT}`); + } catch (err) { + console.error(`${RED_OUT}${BOLD_OUT}error building ${output}${REGULAR_OUT}: ${err.message}${RESET_OUT}`); + throw err; + } + })); +} + +/** + * Build TypeScript definitions using Rollup + rollup-plugin-dts. + */ +async function buildAllTypes() { + const typesOutput = 'build/playcanvas.d.ts'; + console.log(`${CYAN_OUT}${BOLD_OUT}src/index.js${REGULAR_OUT} \u2192 ${BOLD_OUT}${typesOutput}${REGULAR_OUT}...${RESET_OUT}`); + const startTime = performance.now(); + + const { rollup } = await import('rollup'); + const typesConfig = buildTypesOption(); + + const bundle = await rollup({ + input: typesConfig.input, + plugins: typesConfig.plugins + }); + + const outputOptions = Array.isArray(typesConfig.output) ? typesConfig.output : [typesConfig.output]; + await Promise.all(outputOptions.map(output => bundle.write(output))); + await bundle.close(); + + const elapsed = ((performance.now() - startTime) / 1000).toFixed(1); + console.log(`${GREEN_OUT}created ${BOLD_OUT}${typesOutput}${REGULAR_OUT} in ${BOLD_OUT}${elapsed}s${REGULAR_OUT}${RESET_OUT}`); } -const cmd = `rollup -c ${args.join(' ')} ${env.join(' ')}`; -try { - execSync(cmd, { stdio: 'inherit' }); -} catch (e) { - console.error(e.message); +// Main execution +async function main() { + try { + if (jsTargets.length) { + await buildAllJS(); + } + + if (buildTypes) { + await buildAllTypes(); + } + + if (watchMode) { + console.log(`${BLUE_OUT}Watching for changes...${RESET_OUT}`); + let debounceTimer = null; + + fs.watch('src', { recursive: true }, (eventType, filename) => { + if (!filename?.endsWith('.js')) return; + if (debounceTimer) clearTimeout(debounceTimer); + debounceTimer = setTimeout(async () => { + console.log(`\n${BLUE_OUT}Change detected: ${filename}${RESET_OUT}`); + try { + if (jsTargets.length) await buildAllJS(); + if (buildTypes) await buildAllTypes(); + } catch (e) { + console.error(e.message); + } + }, 100); + }); + } + } catch (e) { + console.error(e.message); + if (!watchMode) process.exit(1); + } } + +main(); diff --git a/examples/rollup.config.mjs b/examples/rollup.config.mjs index 5c961b0324a..d06d51c36ba 100644 --- a/examples/rollup.config.mjs +++ b/examples/rollup.config.mjs @@ -7,7 +7,8 @@ import replace from '@rollup/plugin-replace'; import terser from '@rollup/plugin-terser'; import { exampleMetaData } from './cache/metadata.mjs'; -import { buildJSOptions, buildTypesOption } from '../utils/rollup-build-target.mjs'; +import { buildTarget } from '../utils/esbuild-build-target.mjs'; +import { buildTypesOption } from '../utils/rollup-build-target.mjs'; import { version } from '../utils/rollup-version-revision.mjs'; import { buildHtml } from './utils/plugins/rollup-build-html.mjs'; import { buildShare } from './utils/plugins/rollup-build-share.mjs'; @@ -182,18 +183,41 @@ const EXAMPLE_TARGETS = exampleMetaData.flatMap(({ categoryKebab, exampleNameKeb return options; }); -const ENGINE_TARGETS = (() => { +/** + * Build engine JS targets with esbuild before Rollup runs. + * Replaces the previous Rollup-based buildJSOptions calls. + */ +async function buildEngineJS() { + const builds = []; + const opts = { + moduleFormat: /** @type {'esm'} */ ('esm'), + bundleState: /** @type {'bundled'} */ ('bundled'), + input: '../src/index.js', + dir: 'dist/iframe' + }; + + if (NODE_ENV === 'production') { + builds.push(buildTarget({ ...opts, buildType: 'release' })); + } + if (NODE_ENV === 'production' || NODE_ENV === 'development') { + builds.push(buildTarget({ ...opts, buildType: 'debug' })); + } + if (NODE_ENV === 'production' || NODE_ENV === 'profiler') { + builds.push(buildTarget({ ...opts, buildType: 'profiler' })); + } + + await Promise.all(builds); +} + +const ENGINE_TYPES_TARGETS = (() => { /** @type {RollupOptions[]} */ const options = []; - // Types - // Outputs: dist/iframe/playcanvas.d.ts options.push(buildTypesOption({ root: '..', dir: 'dist/iframe' })); - // Sources if (ENGINE_PATH) { const src = path.resolve(ENGINE_PATH); const content = fs.readFileSync(src, 'utf8'); @@ -210,49 +234,12 @@ const ENGINE_TARGETS = (() => { dest: 'dist/iframe/ENGINE_PATH/index.js' })); } - return options; } - // Builds - if (NODE_ENV === 'production') { - // Outputs: dist/iframe/playcanvas.mjs - options.push( - ...buildJSOptions({ - moduleFormat: 'esm', - buildType: 'release', - bundleState: 'bundled', - input: '../src/index.js', - dir: 'dist/iframe' - }) - ); - } - if (NODE_ENV === 'production' || NODE_ENV === 'development') { - // Outputs: dist/iframe/playcanvas.dbg.mjs - options.push( - ...buildJSOptions({ - moduleFormat: 'esm', - buildType: 'debug', - bundleState: 'bundled', - input: '../src/index.js', - dir: 'dist/iframe' - }) - ); - } - if (NODE_ENV === 'production' || NODE_ENV === 'profiler') { - // Outputs: dist/iframe/playcanvas.prf.mjs - options.push( - ...buildJSOptions({ - moduleFormat: 'esm', - buildType: 'profiler', - bundleState: 'bundled', - input: '../src/index.js', - dir: 'dist/iframe' - }) - ); - } return options; })(); +/** @type {RollupOptions[]} */ const APP_TARGETS = [{ // A debug build is ~2.3MB and a release build ~0.6MB input: 'src/app/index.mjs', @@ -288,9 +275,15 @@ const APP_TARGETS = [{ ] }]; -export default [ - ...STATIC_TARGETS, - ...EXAMPLE_TARGETS, - ...ENGINE_TARGETS, - ...APP_TARGETS -]; +export default async () => { + if (!ENGINE_PATH) { + await buildEngineJS(); + } + + return [ + ...STATIC_TARGETS, + ...EXAMPLE_TARGETS, + ...ENGINE_TYPES_TARGETS, + ...APP_TARGETS + ]; +}; diff --git a/package-lock.json b/package-lock.json index 59ce634ca81..c7d532b7ede 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,31 +15,28 @@ "devDependencies": { "@playcanvas/eslint-config": "2.1.0", "@rollup/plugin-node-resolve": "16.0.3", - "@rollup/plugin-strip": "3.0.4", - "@rollup/plugin-swc": "0.4.0", "@rollup/plugin-terser": "0.4.4", - "@rollup/pluginutils": "5.3.0", - "@swc/core": "1.15.30", "@types/node": "24.12.2", "c8": "10.1.3", "chai": "6.2.2", + "esbuild": "^0.25.2", "eslint": "9.39.4", "fflate": "0.8.2", "globals": "17.5.0", + "jscc": "^1.1.1", "jsdom": "28.1.0", "mocha": "11.7.5", "nise": "6.1.5", "publint": "0.3.18", "rollup": "4.60.2", "rollup-plugin-dts": "6.4.1", - "rollup-plugin-jscc": "2.0.0", - "rollup-plugin-visualizer": "6.0.11", "serve": "14.2.6", "sinon": "21.1.2", "typedoc": "0.28.19", "typedoc-plugin-mdn-links": "5.1.1", "typedoc-plugin-missing-exports": "4.1.3", - "typescript": "5.9.3" + "typescript": "5.9.3", + "unplugin-strip": "^0.2.1" }, "engines": { "node": ">=18.0.0" @@ -289,205 +286,630 @@ "node": ">=18" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", + "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=18" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/@esbuild/android-arm": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", + "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", + "cpu": [ + "arm" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "node_modules/@esbuild/android-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", + "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@eslint/config-array": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", - "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "node_modules/@esbuild/android-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", + "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.5" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", + "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", + "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", + "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", + "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^6.14.0", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.5", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "node_modules/@esbuild/linux-arm": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", + "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", + "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@eslint/js": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", + "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" + "node": ">=18" } }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", + "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", + "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@exodus/bytes": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.14.1.tgz", - "integrity": "sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", + "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" - }, - "peerDependencies": { - "@noble/hashes": "^1.8.0 || ^2.0.0" - }, - "peerDependenciesMeta": { - "@noble/hashes": { - "optional": true - } + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", + "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", + "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", + "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", + "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", + "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", + "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", + "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", + "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", + "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", + "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", + "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.14.1.tgz", + "integrity": "sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } } }, "node_modules/@gerrit0/mini-shiki": { @@ -729,52 +1151,6 @@ } } }, - "node_modules/@rollup/plugin-strip": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-strip/-/plugin-strip-3.0.4.tgz", - "integrity": "sha512-LDRV49ZaavxUo2YoKKMQjCxzCxugu1rCPQa0lDYBOWLj6vtzBMr8DcoJjsmg+s450RbKbe3qI9ZLaSO+O1oNbg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.3" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-swc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-swc/-/plugin-swc-0.4.0.tgz", - "integrity": "sha512-oAtqXa8rOl7BOK1Rz3rRxI+LIL53S9SqO2KSq2UUUzWgOgXg6492Jh5mL2mv/f9cpit8zFWdwILuVeozZ0C8mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "smob": "^1.4.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "@swc/core": "^1.3.0", - "rollup": "^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "node_modules/@rollup/plugin-terser": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", @@ -944,590 +1320,328 @@ "license": "MIT", "optional": true, "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", - "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", - "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", - "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", - "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", - "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", - "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", - "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", - "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", - "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", - "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", - "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", - "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", - "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" + "linux" ] }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { + "node_modules/@rollup/rollup-linux-arm64-musl": { "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", - "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", + "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", "cpu": [ - "ia32" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ] }, - "node_modules/@rollup/rollup-win32-x64-gnu": { + "node_modules/@rollup/rollup-linux-loong64-gnu": { "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", - "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", + "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", "cpu": [ - "x64" + "loong64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ] }, - "node_modules/@rollup/rollup-win32-x64-msvc": { + "node_modules/@rollup/rollup-linux-loong64-musl": { "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", - "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", + "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", "cpu": [ - "x64" + "loong64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ] }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", - "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.23.0", - "@shikijs/vscode-textmate": "^10.0.2" - } - }, - "node_modules/@shikijs/langs": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", - "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.23.0" - } - }, - "node_modules/@shikijs/themes": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", - "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.23.0" - } - }, - "node_modules/@shikijs/types": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", - "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "15.3.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", - "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, - "node_modules/@sinonjs/samsam": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-10.0.2.tgz", - "integrity": "sha512-8lVwD1Df1BmzoaOLhMcGGcz/Jyr5QY2KSB75/YK1QgKzoabTeLdIVyhXNZK9ojfSKSdirbXqdbsXXqP9/Ve8+A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1", - "type-detect": "^4.1.0" - } - }, - "node_modules/@sinonjs/samsam/node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@swc/core": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.30.tgz", - "integrity": "sha512-R8VQbQY1BZcbIF2p3gjlTCwAQzx1A194ugWfwld5y+WgVVWqVKm7eURGGOVbQVubgKWzidP2agomBbg96rZilQ==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.26" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.15.30", - "@swc/core-darwin-x64": "1.15.30", - "@swc/core-linux-arm-gnueabihf": "1.15.30", - "@swc/core-linux-arm64-gnu": "1.15.30", - "@swc/core-linux-arm64-musl": "1.15.30", - "@swc/core-linux-ppc64-gnu": "1.15.30", - "@swc/core-linux-s390x-gnu": "1.15.30", - "@swc/core-linux-x64-gnu": "1.15.30", - "@swc/core-linux-x64-musl": "1.15.30", - "@swc/core-win32-arm64-msvc": "1.15.30", - "@swc/core-win32-ia32-msvc": "1.15.30", - "@swc/core-win32-x64-msvc": "1.15.30" - }, - "peerDependencies": { - "@swc/helpers": ">=0.5.17" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.30.tgz", - "integrity": "sha512-VvpP+vq08HmGYewMWvrdsxh9s2lthz/808zXm8Yu5kaqeR8Yia2b0eYXleHQ3VAjoStUDk6LzTheBW9KXYQdMA==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", + "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", "cpu": [ - "arm64" + "ppc64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } + "linux" + ] }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.30.tgz", - "integrity": "sha512-WiJA0hiZI3nwQAO6mu5RqigtWGDtth4Hiq6rbZxAaQyhIcqKIg5IoMRc1Y071lrNJn29eEDMC86Rq58xgUxlDg==", + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", + "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", "cpu": [ - "x64" + "ppc64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } + "linux" + ] }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.30.tgz", - "integrity": "sha512-YANuFUo48kIT6plJgCD0keae9HFXfjxsbvsgevqc0hr/07X/p7sAWTFOGYEc2SXcASaK7UvuQqzlbW8pr7R79g==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", + "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", "cpu": [ - "arm" + "riscv64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.30.tgz", - "integrity": "sha512-VndG8jaR4ugY6u+iVOT0Q+d2fZd7sLgjPgN8W/Le+3EbZKl+cRfFxV7Eoz4gfLqhmneZPdcIzf9T3LkgkmqNLg==", + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", + "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", "cpu": [ - "arm64" + "riscv64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.30.tgz", - "integrity": "sha512-1SYGs2l0Yyyi0pR/P/NKz/x0kqxkoiw+BXeJjLUdecSk/KasncWlJrc6hOvFSgKHOBrzgM5jwuluKtlT8dnrcA==", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", + "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", "cpu": [ - "arm64" + "s390x" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-linux-ppc64-gnu": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.30.tgz", - "integrity": "sha512-TXREtiXeRhbfDFbmhnkIsXpKfzbfT73YkV2ZF6w0sfxgjC5zI2ZAbaCOq25qxvegofj2K93DtOpm9RLaBgqR2g==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", + "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", "cpu": [ - "ppc64" + "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-linux-s390x-gnu": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.30.tgz", - "integrity": "sha512-DCR2YYeyd6DQE4OuDhImouuNcjXEiEdnn1Y0DyGteugPEDvVuvYk8Xddi+4o2SgWH6jiW8/I+3emZvbep1NC+g==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", + "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", "cpu": [ - "s390x" + "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.30.tgz", - "integrity": "sha512-5Pizw3NgfOJ5BJOBK8TIRa59xFW2avESTOBDPTAYwZYa1JNDs+KMF9lUfjJiJLM5HiMs/wPheA9eiT0q9m2AoA==", + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", + "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } + "openbsd" + ] }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.30.tgz", - "integrity": "sha512-qyqydP/wyH8alcIP4a2hnGSjHLJjm9H7yDFup+CPy9oTahFgLLwnNcv5UHXqO2Qs3AIND+cls5f/Bb6hqpxdgA==", + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", + "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", "cpu": [ - "x64" + "arm64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } + "openharmony" + ] }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.30.tgz", - "integrity": "sha512-CaQENgDHVGOg1mSF5sQVgvfFHG9kjMor2rkLMLeLOkfZYNj13ppnJ9+lfaBZLZUMMbnlGQnavCJb8PVBUOso7Q==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", + "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.30.tgz", - "integrity": "sha512-30VdLeGk6fugiUs/kUdJ/pAg7z/zpvVbR11RH60jZ0Z42WIeIniYx0rLEWN7h/pKJ3CopqsQ3RsogCAkRKiA2g==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", + "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", "cpu": [ "ia32" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.15.30", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.30.tgz", - "integrity": "sha512-4iObHPR+Q4oDY110EF5SF5eIaaVJNpMdG9C0q3Q92BsJ5y467uHz7sYQhP60WYlLFsLQ1el2YrIPUItUAQGOKg==", + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", + "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", + "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", + "cpu": [ + "x64" ], - "engines": { - "node": ">=10" + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" } }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", "dev": true, - "license": "Apache-2.0" + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } }, - "node_modules/@swc/types": { - "version": "0.1.26", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.26.tgz", - "integrity": "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==", + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", + "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-10.0.2.tgz", + "integrity": "sha512-8lVwD1Df1BmzoaOLhMcGGcz/Jyr5QY2KSB75/YK1QgKzoabTeLdIVyhXNZK9ojfSKSdirbXqdbsXXqP9/Ve8+A==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@swc/counter": "^0.1.3" + "@sinonjs/commons": "^3.0.1", + "type-detect": "^4.1.0" + } + }, + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" } }, "node_modules/@types/estree": { @@ -2969,6 +3083,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", + "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.2", + "@esbuild/android-arm": "0.25.2", + "@esbuild/android-arm64": "0.25.2", + "@esbuild/android-x64": "0.25.2", + "@esbuild/darwin-arm64": "0.25.2", + "@esbuild/darwin-x64": "0.25.2", + "@esbuild/freebsd-arm64": "0.25.2", + "@esbuild/freebsd-x64": "0.25.2", + "@esbuild/linux-arm": "0.25.2", + "@esbuild/linux-arm64": "0.25.2", + "@esbuild/linux-ia32": "0.25.2", + "@esbuild/linux-loong64": "0.25.2", + "@esbuild/linux-mips64el": "0.25.2", + "@esbuild/linux-ppc64": "0.25.2", + "@esbuild/linux-riscv64": "0.25.2", + "@esbuild/linux-s390x": "0.25.2", + "@esbuild/linux-x64": "0.25.2", + "@esbuild/netbsd-arm64": "0.25.2", + "@esbuild/netbsd-x64": "0.25.2", + "@esbuild/openbsd-arm64": "0.25.2", + "@esbuild/openbsd-x64": "0.25.2", + "@esbuild/sunos-x64": "0.25.2", + "@esbuild/win32-arm64": "0.25.2", + "@esbuild/win32-ia32": "0.25.2", + "@esbuild/win32-x64": "0.25.2" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -5931,100 +6086,6 @@ "typescript": "^4.5 || ^5.0 || ^6.0" } }, - "node_modules/rollup-plugin-jscc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-jscc/-/rollup-plugin-jscc-2.0.0.tgz", - "integrity": "sha512-5jG9q79K2u5uRBTKA+GA4gqt1zA7qHQRpcabZMoVs913gr75s428O7K3r58n2vADDzwIhiOKMo7rCMhOyks6dw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jsbits/get-package-version": "^1.0.3", - "jscc": "^1.1.1", - "rollup-pluginutils": "^2.8.2" - }, - "engines": { - "node": ">=10.12.0" - }, - "peerDependencies": { - "rollup": ">=2" - } - }, - "node_modules/rollup-plugin-visualizer": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-6.0.11.tgz", - "integrity": "sha512-TBwVHVY7buHjIKVLqr9scTVFwqZqMXINcCphPwIWKPDCOBIa+jCQfafvbjRJDZgXdq/A996Dy6yGJ/+/NtAXDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "open": "^8.0.0", - "picomatch": "^4.0.2", - "source-map": "^0.7.4", - "yargs": "^17.5.1" - }, - "bin": { - "rollup-plugin-visualizer": "dist/bin/cli.js" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "rolldown": "1.x || ^1.0.0-beta", - "rollup": "2.x || 3.x || 4.x" - }, - "peerDependenciesMeta": { - "rolldown": { - "optional": true - }, - "rollup": { - "optional": true - } - } - }, - "node_modules/rollup-plugin-visualizer/node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/rollup-plugin-visualizer/node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "estree-walker": "^0.6.1" - } - }, - "node_modules/rollup-pluginutils/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true, - "license": "MIT" - }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -6523,16 +6584,6 @@ "dev": true, "license": "MIT" }, - "node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -7266,6 +7317,71 @@ "dev": true, "license": "MIT" }, + "node_modules/unplugin": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", + "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/unplugin-strip": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/unplugin-strip/-/unplugin-strip-0.2.1.tgz", + "integrity": "sha512-Z5DgWyVhDVBs8zwyzo27g0biiu36nGJsj/xtyeUywdbB1XTHrlBudRYmoKx+a28uK18A5Mg1+tWsB7yHv8l8dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.11", + "unplugin": "^1.12.0" + }, + "peerDependencies": { + "@nuxt/kit": "^3", + "@nuxt/schema": "^3", + "esbuild": "*", + "rollup": "^3", + "vite": ">=3", + "webpack": "^4 || ^5" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + }, + "@nuxt/schema": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "rollup": { + "optional": true + }, + "vite": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/unplugin-strip/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/update-check": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz", @@ -7342,6 +7458,13 @@ "node": ">=20" } }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + }, "node_modules/whatwg-mimetype": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", diff --git a/package.json b/package.json index 20ed3ff6339..38a521da771 100644 --- a/package.json +++ b/package.json @@ -88,31 +88,28 @@ "devDependencies": { "@playcanvas/eslint-config": "2.1.0", "@rollup/plugin-node-resolve": "16.0.3", - "@rollup/plugin-strip": "3.0.4", - "@rollup/plugin-swc": "0.4.0", "@rollup/plugin-terser": "0.4.4", - "@rollup/pluginutils": "5.3.0", - "@swc/core": "1.15.30", "@types/node": "24.12.2", "c8": "10.1.3", "chai": "6.2.2", + "esbuild": "^0.25.2", "eslint": "9.39.4", "fflate": "0.8.2", "globals": "17.5.0", + "jscc": "^1.1.1", "jsdom": "28.1.0", "mocha": "11.7.5", "nise": "6.1.5", "publint": "0.3.18", "rollup": "4.60.2", "rollup-plugin-dts": "6.4.1", - "rollup-plugin-jscc": "2.0.0", - "rollup-plugin-visualizer": "6.0.11", "serve": "14.2.6", "sinon": "21.1.2", "typedoc": "0.28.19", "typedoc-plugin-mdn-links": "5.1.1", "typedoc-plugin-missing-exports": "4.1.3", - "typescript": "5.9.3" + "typescript": "5.9.3", + "unplugin-strip": "^0.2.1" }, "optionalDependencies": { "canvas": "3.2.3" @@ -131,7 +128,6 @@ "build:treenet": "npm run build target:release treenet", "build:treesun": "npm run build target:release treesun", "build:treeflame": "npm run build target:release treeflame", - "build:sourcemaps": "npm run build -- -m", "watch": "npm run build -- -w", "watch:release": "npm run build target:release -- -w", "watch:debug": "npm run build target:debug -- -w", diff --git a/rollup.config.mjs b/rollup.config.mjs index 98aa339171e..c48807b9db6 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -1,79 +1,10 @@ -import fs from 'fs'; -import { version, revision } from './utils/rollup-version-revision.mjs'; -import { buildJSOptions, buildTypesOption } from './utils/rollup-build-target.mjs'; - -/** @import { RollupOptions } from 'rollup' */ - -const BLUE_OUT = '\x1b[34m'; -const RED_OUT = '\x1b[31m'; -const BOLD_OUT = '\x1b[1m'; -const REGULAR_OUT = '\x1b[22m'; -const RESET_OUT = '\x1b[0m'; - -const BUILD_TYPES = /** @type {const} */ (['release', 'debug', 'profiler', 'min']); -const MODULE_FORMAT = /** @type {const} */ (['umd', 'esm']); -const BUNDLE_STATES = /** @type {const} */ (['unbundled', 'bundled']); - -const envTarget = process.env.target ? process.env.target.toLowerCase() : null; - -const title = [ - 'Building PlayCanvas Engine', - `version ${BOLD_OUT}v${version}${REGULAR_OUT}`, - `revision ${BOLD_OUT}${revision}${REGULAR_OUT}`, - `target ${BOLD_OUT}${envTarget ?? 'all'}${REGULAR_OUT}` -].join('\n'); -console.log(`${BLUE_OUT}${title}${RESET_OUT}`); - -if (envTarget === null && fs.existsSync('build')) { - // no targets specified, clean build directory - fs.rmSync('build', { recursive: true }); -} - -function includeBuild(buildType, moduleFormat, bundleState) { - return envTarget === null || - envTarget === buildType || - envTarget === moduleFormat || - envTarget === bundleState || - envTarget === `${moduleFormat}:${buildType}` || - envTarget === `${moduleFormat}:${bundleState}` || - envTarget === `${buildType}:${bundleState}` || - envTarget === `${moduleFormat}:${buildType}:${bundleState}`; -} - /** - * @type {RollupOptions[]} + * Rollup configuration — retained for types build only. + * JS builds are now handled by esbuild via build.mjs. + * + * This config is used by the examples build which imports buildJSOptions/buildTypesOption + * from utils/rollup-build-target.mjs. */ -const targets = []; -BUILD_TYPES.forEach((buildType) => { - MODULE_FORMAT.forEach((moduleFormat) => { - BUNDLE_STATES.forEach((bundleState) => { - if (bundleState === 'unbundled' && moduleFormat === 'umd') { - return; - } - if (bundleState === 'unbundled' && buildType === 'min') { - return; - } - - if (!includeBuild(buildType, moduleFormat, bundleState)) { - return; - } - - targets.push(...buildJSOptions({ - moduleFormat, - buildType, - bundleState - })); - }); - }); -}); - -if (envTarget === null || envTarget === 'types') { - targets.push(buildTypesOption()); -} - -if (!targets.length) { - console.error(`${RED_OUT}${BOLD_OUT}No targets found${RESET_OUT}`); - process.exit(1); -} +import { buildTypesOption } from './utils/rollup-build-target.mjs'; -export default targets; +export default [buildTypesOption()]; diff --git a/utils/esbuild-build-target.mjs b/utils/esbuild-build-target.mjs new file mode 100644 index 00000000000..6eb6350ef8d --- /dev/null +++ b/utils/esbuild-build-target.mjs @@ -0,0 +1,310 @@ +import esbuild from 'esbuild'; +import fs from 'fs'; +import { + dirname, join as pathJoin, relative as pathRelative, + resolve as pathResolve, posix, sep +} from 'path'; +import { fileURLToPath } from 'url'; + +import { importValidationPlugin } from './plugins/esbuild-import-validation.mjs'; +import { + applyTransforms, createStripTransform, transformPipelinePlugin +} from './plugins/esbuild-transform-pipeline.mjs'; +import { version, revision } from './rollup-version-revision.mjs'; +import { getBanner } from './rollup-get-banner.mjs'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const rootDir = pathResolve(__dirname, '..'); + +const STRIP_FUNCTIONS = [ + 'Debug.assert', + 'Debug.assertDeprecated', + 'Debug.assertDestroyed', + 'Debug.call', + 'Debug.deprecated', + 'Debug.warn', + 'Debug.warnOnce', + 'Debug.error', + 'Debug.errorOnce', + 'Debug.log', + 'Debug.logOnce', + 'Debug.removed', + 'Debug.trace', + 'DebugHelper.setName', + 'DebugHelper.setLabel', + 'DebugHelper.setDestroyed', + 'DebugGraphics.toString', + 'DebugGraphics.clearGpuMarkers', + 'DebugGraphics.pushGpuMarker', + 'DebugGraphics.popGpuMarker', + 'WebgpuDebug.validate', + 'WebgpuDebug.memory', + 'WebgpuDebug.internal', + 'WebgpuDebug.end', + 'WebgpuDebug.endShader', + 'WorldClustersDebug.render' +]; + +const BANNER = { + debug: ' (DEBUG)', + release: ' (RELEASE)', + profiler: ' (PROFILE)', + min: ' (RELEASE)' +}; + +const OUT_PREFIX = { + debug: 'playcanvas.dbg', + release: 'playcanvas', + profiler: 'playcanvas.prf', + min: 'playcanvas.min' +}; + +/** + * Get JSCC values for a given build type. + * + * @param {'debug'|'release'|'profiler'} buildType - The build type. + * @returns {{ values: Object, keepLines: boolean }} JSCC config. + */ +function getJSCCConfig(buildType) { + const base = { + _CURRENT_SDK_VERSION: version, + _CURRENT_SDK_REVISION: revision + }; + + switch (buildType) { + case 'debug': + return { + values: { ...base, _DEBUG: 1, _PROFILER: 1 }, + keepLines: true + }; + case 'profiler': + return { + values: { ...base, _PROFILER: 1 }, + keepLines: false + }; + case 'release': + default: + return { values: base, keepLines: false }; + } +} + +/** + * Collect all .js files under a directory recursively. + * + * @param {string} dirPath - Directory to scan. + * @returns {string[]} List of file paths. + */ +function collectJSFiles(dirPath) { + const files = []; + const entries = fs.readdirSync(dirPath, { withFileTypes: true }); + for (const entry of entries) { + const full = pathJoin(dirPath, entry.name); + if (entry.isDirectory()) { + files.push(...collectJSFiles(full)); + } else if (entry.isFile() && entry.name.endsWith('.js')) { + files.push(full); + } + } + return files; +} + +/** + * Build a bundled JS target (single output file). + * + * @param {object} options - Build options. + * @param {'umd'|'esm'} options.moduleFormat - The module format. + * @param {'debug'|'release'|'profiler'|'min'} options.buildType - The build type. + * @param {string} [options.input] - Entry point (default: 'src/index.js'). + * @param {string} [options.dir] - Output directory (default: 'build'). + * @returns {Promise} + */ +async function buildBundled({ + moduleFormat, + buildType, + input = 'src/index.js', + dir = 'build' +}) { + const isUMD = moduleFormat === 'umd'; + const isDebug = buildType === 'debug'; + const isMin = buildType === 'min'; + const prefix = OUT_PREFIX[buildType]; + const outfile = `${dir}/${prefix}${isUMD ? '.js' : '.mjs'}`; + const effectiveBuildType = buildType === 'min' ? 'release' : buildType; + const jsccConfig = getJSCCConfig(effectiveBuildType); + + const banner = getBanner(BANNER[buildType]); + + const plugins = [ + transformPipelinePlugin({ + jsccValues: jsccConfig.values, + jsccKeepLines: jsccConfig.keepLines, + stripFunctions: !isDebug ? STRIP_FUNCTIONS : null, + processShaders: !isDebug, + dynamicImportLegacy: isUMD, + dynamicImportSuppress: !isUMD, + stripComments: !isDebug + }) + ]; + + if (isDebug) { + plugins.push(importValidationPlugin(input)); + } + + /** @type {import('esbuild').BuildOptions} */ + const opts = { + entryPoints: [input], + bundle: true, + outfile, + format: isUMD ? 'iife' : 'esm', + globalName: isUMD ? 'pc' : undefined, + target: 'es2020', + sourcemap: isDebug ? 'inline' : false, + minify: isMin, + legalComments: 'none', + banner: { js: banner }, + plugins, + external: ['node:worker_threads'], + logLevel: 'warning' + }; + + if (isMin) { + opts.drop = ['console']; + } + + if (isUMD) { + opts.banner = { + js: [ + banner, + '(function (root, factory) {', + '\tif (typeof module !== \'undefined\' && module.exports) {', + '\t\tmodule.exports = factory();', + '\t} else if (typeof define === \'function\' && define.amd) {', + '\t\tdefine(factory);', + '\t} else {', + '\t\troot.pc = factory();', + '\t}', + '}(typeof self !== \'undefined\' ? self : this, function () {' + ].join('\n') + }; + opts.footer = { + js: 'return pc;\n}));' + }; + opts.format = 'esm'; + } + + await esbuild.build(opts); +} + +/** + * Build an unbundled JS target (per-file transform, preserving module structure). + * + * @param {object} options - Build options. + * @param {'debug'|'release'|'profiler'} options.buildType - The build type. + * @param {string} [options.input] - Entry point directory root (default: 'src'). + * @param {string} [options.dir] - Output base directory (default: 'build'). + * @returns {Promise} + */ +async function buildUnbundled({ + buildType, + input = 'src', + dir = 'build' +}) { + const isDebug = buildType === 'debug'; + const prefix = OUT_PREFIX[buildType]; + const outDir = `${dir}/${prefix}`; + const effectiveBuildType = buildType === 'min' ? 'release' : buildType; + const jsccConfig = getJSCCConfig(effectiveBuildType); + const strip = + !isDebug ? createStripTransform(STRIP_FUNCTIONS) : null; + + const srcFiles = collectJSFiles(input); + + const transformPromises = srcFiles.map(async (srcFile) => { + let source = await fs.promises.readFile(srcFile, 'utf8'); + + source = applyTransforms(source, { + jsccValues: jsccConfig.values, + jsccKeepLines: jsccConfig.keepLines, + strip, + processShaders: !isDebug, + dynamicImportLegacy: false, + dynamicImportSuppress: true, + stripComments: !isDebug + }); + + // Rewrite bare 'fflate' import to relative modules path + if (source.includes('from \'fflate\'') || + source.includes('from "fflate"')) { + const relFromSrc = pathRelative(dirname(srcFile), input); + const modulePath = posix.join( + relFromSrc.split(sep).join('/'), + '..', 'modules', 'fflate', 'esm', 'browser.js' + ); + source = source.replace( + /from ['"]fflate['"]/g, + `from '${modulePath}'` + ); + } + + // Skip files that have no meaningful content after transforms + if (!isDebug) { + const meaningful = source + .replace(/\/\*[\s\S]*?\*\//g, '') + .replace(/\/\/.*/g, '') + .replace(/^\s*import\s.*$/gm, '') + .replace(/^\s*export\s.*$/gm, '') + .trim(); + if (meaningful.length === 0) { + return; + } + } + + const destFile = pathJoin(outDir, srcFile); + await fs.promises.mkdir(dirname(destFile), { recursive: true }); + await fs.promises.writeFile(destFile, source); + }); + + await Promise.all(transformPromises); + + // Copy fflate module into unbundled output + const fflateEntry = pathJoin( + rootDir, 'node_modules', 'fflate', 'esm', 'browser.js' + ); + const destDir = pathJoin(outDir, 'modules', 'fflate', 'esm'); + fs.mkdirSync(destDir, { recursive: true }); + fs.copyFileSync(fflateEntry, pathJoin(destDir, 'browser.js')); +} + +/** + * Build a single JS target (bundled or unbundled). + * + * @param {object} options - Build options. + * @param {'umd'|'esm'} options.moduleFormat - The module format. + * @param {'debug'|'release'|'profiler'|'min'} options.buildType - The build type. + * @param {'unbundled'|'bundled'} [options.bundleState] - The bundle state. + * @param {string} [options.input] - Entry point. + * @param {string} [options.dir] - Output directory. + * @returns {Promise} + */ +async function buildTarget({ + moduleFormat, + buildType, + bundleState, + input = 'src/index.js', + dir = 'build' +}) { + const isUMD = moduleFormat === 'umd'; + const isMin = buildType === 'min'; + const bundled = isUMD || isMin || bundleState === 'bundled'; + + if (bundled) { + await buildBundled({ moduleFormat, buildType, input, dir }); + } else { + await buildUnbundled({ + buildType, input: dirname(input), dir + }); + } +} + +export { buildTarget, OUT_PREFIX }; diff --git a/utils/plugins/esbuild-dynamic.mjs b/utils/plugins/esbuild-dynamic.mjs new file mode 100644 index 00000000000..bd40ab0be36 --- /dev/null +++ b/utils/plugins/esbuild-dynamic.mjs @@ -0,0 +1,20 @@ +/** + * Wrap dynamic `import()` calls in `new Function(...)` for legacy browser support (UMD builds). + * + * @param {string} source - Source code. + * @returns {string} Transformed source. + */ +export function applyDynamicImportLegacy(source) { + return source.replace(/(\W)import\(/g, '$1new Function("modulePath", "return import(modulePath)")('); +} + +/** + * Add bundler-suppress comments before dynamic `import()` calls + * to quiet Vite/webpack warnings (ESM builds). + * + * @param {string} source - Source code. + * @returns {string} Transformed source. + */ +export function applyDynamicImportSuppress(source) { + return source.replace(/import\(([^'])/g, 'import(/* @vite-ignore */ /* webpackIgnore: true */ $1'); +} diff --git a/utils/plugins/esbuild-import-validation.mjs b/utils/plugins/esbuild-import-validation.mjs new file mode 100644 index 00000000000..2023ba6a4c7 --- /dev/null +++ b/utils/plugins/esbuild-import-validation.mjs @@ -0,0 +1,49 @@ +import path from 'node:path'; + +/** + * esbuild plugin that validates engine layer imports. + * Warns when a lower-level module imports from a higher-level module. + * + * Hierarchy: core (0) → platform (1) → scene (2) → framework (3) → extras (4) + * + * Port of engineLayerImportValidation from rollup-import-validation.mjs. + * + * @param {string} rootFile - The root file, typically `src/index.js`. + * @returns {import('esbuild').Plugin} The esbuild plugin. + */ +export function importValidationPlugin(rootFile) { + const folderLevels = { + 'core': 0, + 'platform': 1, + 'scene': 2, + 'framework': 3, + 'extras': 4 + }; + + const rootPath = path.parse(path.resolve(rootFile)).dir; + + return { + name: 'import-validation', + setup(build) { + build.onResolve({ filter: /^\./ }, (args) => { + if (!args.importer) return undefined; + + const importerDir = path.parse(args.importer).dir; + const relImporter = path.dirname(path.relative(rootPath, args.importer)); + const folderImporter = relImporter.split(path.sep)[0]; + const levelImporter = folderLevels[folderImporter]; + + const absImported = path.resolve(path.join(importerDir, args.path)); + const relImported = path.dirname(path.relative(rootPath, absImported)); + const folderImported = relImported.split(path.sep)[0]; + const levelImported = folderLevels[folderImported]; + + if (levelImporter !== undefined && levelImported !== undefined && levelImporter < levelImported) { + console.log(`(!) Incorrect import: [${path.relative(rootPath, args.importer)}] -> [${args.path}]`); + } + + return undefined; + }); + } + }; +} diff --git a/utils/plugins/esbuild-jscc.mjs b/utils/plugins/esbuild-jscc.mjs new file mode 100644 index 00000000000..5d38e328fd6 --- /dev/null +++ b/utils/plugins/esbuild-jscc.mjs @@ -0,0 +1,17 @@ +import jscc from 'jscc'; + +/** + * Apply JSCC processing to source text. + * + * Processes `// #if _VAR` / `// #else` / `// #endif` comment-based directives + * and replaces `$_VAR` value tokens in source code. + * + * @param {string} source - Source code. + * @param {Object} values - Map of variable names to values. + * @param {boolean} keepLines - Preserve line count by replacing removed lines with blanks. + * @returns {string} Processed source. + */ +export function processJSCC(source, values, keepLines) { + const result = jscc(source, null, { values, keepLines, sourceMap: false, prefixes: ['// '] }); + return result.code; +} diff --git a/utils/plugins/esbuild-shader-chunks.mjs b/utils/plugins/esbuild-shader-chunks.mjs new file mode 100644 index 00000000000..cda46ddd5a3 --- /dev/null +++ b/utils/plugins/esbuild-shader-chunks.mjs @@ -0,0 +1,19 @@ +/** + * Minify shader code inside template literals marked with + * `/* glsl *\/` or `/* wgsl *\/` comments. + * + * @param {string} source - Source code. + * @returns {string} Processed source. + */ +export function processShaderChunks(source) { + return source.replace(/\/\* *(glsl|wgsl) *\*\/\s*(`.*?`)/gs, (match, type, code) => { + return code + .trim() + .replace(/\r/g, '') + .replace(/ {4}/g, '\t') + .replace(/[ \t]*\/\/.*/g, '') + .replace(/[ \t]*\/\*[\s\S]*?\*\//g, '') + .concat('\n') + .replace(/\n{2,}/g, '\n'); + }); +} diff --git a/utils/plugins/esbuild-strip.mjs b/utils/plugins/esbuild-strip.mjs new file mode 100644 index 00000000000..8156e14a103 --- /dev/null +++ b/utils/plugins/esbuild-strip.mjs @@ -0,0 +1,33 @@ +import { parse } from 'acorn'; +import { unpluginFactory } from 'unplugin-strip'; + +/** + * Create a strip transform function for the given function names. + * Uses unplugin-strip (AST-based) to reliably remove function calls + * in all positions — statement-level, inline, inside template literals, etc. + * + * @param {string[]} functions - Function names to strip (e.g. 'Debug.assert'). + * @returns {(source: string) => string} Transform function. + */ +export function createStripTransform(functions) { + const plugin = unpluginFactory({ + functions, + sourceMap: false, + debugger: false, + include: '**/*.js' + }); + + const ctx = { + parse(code) { + return parse(code, { + ecmaVersion: 'latest', + sourceType: 'module' + }); + } + }; + + return function applyStrip(source) { + const result = plugin.transform.call(ctx, source, 'file.js'); + return result ? result.code : source; + }; +} diff --git a/utils/plugins/esbuild-transform-pipeline.mjs b/utils/plugins/esbuild-transform-pipeline.mjs new file mode 100644 index 00000000000..3782e2c612f --- /dev/null +++ b/utils/plugins/esbuild-transform-pipeline.mjs @@ -0,0 +1,84 @@ +import fs from 'fs'; +import { processJSCC } from './esbuild-jscc.mjs'; +import { createStripTransform } from './esbuild-strip.mjs'; +import { processShaderChunks } from './esbuild-shader-chunks.mjs'; +import { applyDynamicImportLegacy, applyDynamicImportSuppress } from './esbuild-dynamic.mjs'; + +/** + * Apply all source transforms to a string of source code. + * Shared by the esbuild pipeline plugin (bundled builds) and the + * unbundled build path which transforms files directly. + * + * @param {string} source - Source code to transform. + * @param {Object} options - Transform options. + * @param {Object} options.jsccValues - JSCC variable values. + * @param {boolean} options.jsccKeepLines - Preserve line count for JSCC. + * @param {((source: string) => string)|null} options.strip - Strip transform (null = skip). + * @param {boolean} options.processShaders - Whether to minify shader chunks. + * @param {boolean} options.dynamicImportLegacy - Wrap imports for legacy browsers. + * @param {boolean} options.dynamicImportSuppress - Add bundler-suppress comments. + * @param {boolean} options.stripComments - Strip JSDoc comments. + * @returns {string} Transformed source. + */ +export function applyTransforms(source, { + jsccValues, jsccKeepLines, strip, + processShaders: doShaders, dynamicImportLegacy, + dynamicImportSuppress, stripComments +}) { + source = processJSCC(source, jsccValues, jsccKeepLines); + if (doShaders) source = processShaderChunks(source); + if (strip) source = strip(source); + if (stripComments) source = source.replace(/\/\*\*[\s\S]*?\*\//g, ''); + if (dynamicImportLegacy) source = applyDynamicImportLegacy(source); + if (dynamicImportSuppress) source = applyDynamicImportSuppress(source); + return source; +} + +export { createStripTransform }; + +/** + * Combined esbuild plugin that applies all source transforms in a single + * onLoad handler. esbuild only runs the FIRST matching onLoad handler per + * file, so all transforms must be in one plugin to chain correctly. + * + * @param {Object} options - Pipeline options. + * @param {Object} options.jsccValues - JSCC variable values. + * @param {boolean} [options.jsccKeepLines] - Preserve line count for JSCC. + * @param {string[]} [options.stripFunctions] - Functions to strip (null = don't strip). + * @param {boolean} [options.processShaders] - Whether to minify shader chunks. + * @param {boolean} [options.dynamicImportLegacy] - Wrap imports for legacy browsers. + * @param {boolean} [options.dynamicImportSuppress] - Add bundler-suppress comments. + * @param {boolean} [options.stripComments] - Strip JSDoc comments. + * @returns {import('esbuild').Plugin} The esbuild plugin. + */ +export function transformPipelinePlugin({ + jsccValues = {}, + jsccKeepLines = false, + stripFunctions = null, + processShaders = false, + dynamicImportLegacy = false, + dynamicImportSuppress = false, + stripComments = false +} = {}) { + const strip = + stripFunctions ? createStripTransform(stripFunctions) : null; + + return { + name: 'transform-pipeline', + setup(build) { + build.onLoad({ filter: /\.js$/ }, async (args) => { + const source = await fs.promises.readFile(args.path, 'utf8'); + const result = applyTransforms(source, { + jsccValues, + jsccKeepLines, + strip, + processShaders, + dynamicImportLegacy, + dynamicImportSuppress, + stripComments + }); + return { contents: result, loader: 'js' }; + }); + } + }; +} diff --git a/utils/plugins/rollup-dynamic.mjs b/utils/plugins/rollup-dynamic.mjs deleted file mode 100644 index e7271b6ad95..00000000000 --- a/utils/plugins/rollup-dynamic.mjs +++ /dev/null @@ -1,39 +0,0 @@ -/** - * This rollup plugin transform code with dynamic import statements and wraps them - * in a `new Function('import("modulePath")')` statement, in order to avoid parsing errors in older browsers - * without support for dynamic imports. - * - * Note that whilst this will prevent parsing errors, it can trigger CSP errors. - * - * @returns {import('rollup').Plugin} The rollup plugin - */ -export function dynamicImportLegacyBrowserSupport() { - return { - name: 'dynamic-import-old-browsers', - transform(code, id) { - return { - code: code.replace(/(\W)import\(/g, '$1new Function("modulePath", "return import(modulePath)")('), - map: null - }; - } - }; -} - -/** - * This rollup plugin transform code with import statements and adds a \/* vite-ignore *\/ comment to suppress bundler warnings - * generated from dynamic-import-vars {@link https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations} - * {@link https://webpack.js.org/api/module-methods/#dynamic-expressions-in-import} - * - * @returns {import('rollup').Plugin} The rollup plugin - */ -export function dynamicImportBundlerSuppress() { - return { - name: 'dynamic-import-bundler-suppress', - transform(code, id) { - return { - code: code.replace(/import\(([^'])/g, 'import(/* @vite-ignore */ /* webpackIgnore: true */ $1'), - map: null - }; - } - }; -} diff --git a/utils/plugins/rollup-import-validation.mjs b/utils/plugins/rollup-import-validation.mjs deleted file mode 100644 index 7d4100deb42..00000000000 --- a/utils/plugins/rollup-import-validation.mjs +++ /dev/null @@ -1,52 +0,0 @@ -import path from 'node:path'; - -/** @typedef {import('rollup').Plugin} Plugin */ - -/** - * Validate and print warning if an engine module on a lower level imports module on a higher level - * - * @param {string} rootFile - The root file, typically `src/index.js`. - * @returns {Plugin} The plugin. - */ -export function engineLayerImportValidation(rootFile) { - - const folderLevels = { - 'core': 0, - 'platform': 1, - 'scene': 2, - 'framework': 3, - 'extras': 4 - }; - - let rootPath; - - return { - name: 'engineLayerImportValidation', - - buildStart() { - rootPath = path.parse(path.resolve(rootFile)).dir; - }, - - resolveId(imported, importer) { - // skip non-relative paths, those are not our imports, for example 'rollupPluginBabelHelpers.js' - if (importer && imported && imported.includes('./')) { - - // convert importer path - const importerDir = path.parse(importer).dir; - const relImporter = path.dirname(path.relative(rootPath, importer)); - const folderImporter = relImporter.split(path.sep)[0]; - const levelImporter = folderLevels[folderImporter]; - - // convert imported path - const absImported = path.resolve(path.join(importerDir, imported)); - const relImported = path.dirname(path.relative(rootPath, absImported)); - const folderImported = relImported.split(path.sep)[0]; - const levelImported = folderLevels[folderImported]; - - if (levelImporter < levelImported) { - console.log(`(!) Incorrect import: [${path.relative(rootPath, importer)}] -> [${imported}]`); - } - } - } - }; -} diff --git a/utils/plugins/rollup-shader-chunks.mjs b/utils/plugins/rollup-shader-chunks.mjs deleted file mode 100644 index 0710b0c7d02..00000000000 --- a/utils/plugins/rollup-shader-chunks.mjs +++ /dev/null @@ -1,49 +0,0 @@ -import { createFilter } from '@rollup/pluginutils'; - -/** @typedef {import('rollup').Plugin} Plugin */ -/** @typedef {string | string[]} GlobPattern */ -/** - * @typedef {Object | null} PluginOptions - * @property {GlobPattern?} include - pattern(s array) to import - * @property {GlobPattern?} exclude - pattern(s array) to ignore - * @property {boolean?} enabled - enable the plugin - */ - -/** - * @type {readonly string[]} - */ -const DEFAULT_SHADERS = Object.freeze(['**/*.js']); - -/** - * @param {PluginOptions} options - Plugin config object - * @returns {Plugin} The plugin that converts shader code. - */ -export function shaderChunks({ - include = DEFAULT_SHADERS, - exclude = undefined -} = {}) { - const filter = createFilter(include, exclude); - - return { - name: 'shaderChunks', - transform(source, shader) { - if (!filter(shader)) return; - - source = source.replace(/\/\* *(glsl|wgsl) *\*\/\s*(`.*?`)/gs, (match, type, code) => { - return code - .trim() // trim whitespace - .replace(/\r/g, '') // Remove carriage returns - .replace(/ {4}/g, '\t') // 4 spaces to tabs - .replace(/[ \t]*\/\/.*/g, '') // remove single line comments - .replace(/[ \t]*\/\*[\s\S]*?\*\//g, '') // remove multi line comments - .concat('\n') // ensure final new line - .replace(/\n{2,}/g, '\n'); // condense 2 or more empty lines to 1 - }); - - return { - code: source, - map: null - }; - } - }; -} diff --git a/utils/plugins/rollup-spaces-to-tabs.mjs b/utils/plugins/rollup-spaces-to-tabs.mjs deleted file mode 100644 index 3a0534e852c..00000000000 --- a/utils/plugins/rollup-spaces-to-tabs.mjs +++ /dev/null @@ -1,34 +0,0 @@ -import { createFilter } from '@rollup/pluginutils'; - -/** @typedef {import('rollup').Plugin} Plugin */ - -/** - * This plugin converts every two spaces into one tab. Two spaces is the default the rollup plugin - * outputs, which is independent of the four spaces of the code base. - * - * @returns {Plugin} The plugin. - */ -export function spacesToTabs() { - const filter = createFilter([ - '**/*.js' - ], []); - - return { - name: 'spacesToTabs', - transform(code, id) { - if (!filter(id)) return undefined; - // ^ = start of line - // " +" = one or more spaces - // gm = find all + multiline - const regex = /^ +/gm; - code = code.replace( - regex, - startSpaces => startSpaces.replace(/ {2}/g, '\t') - ); - return { - code, - map: null - }; - } - }; -} diff --git a/utils/rollup-build-target.mjs b/utils/rollup-build-target.mjs index 06c3dbe76b2..738e05ea7c4 100644 --- a/utils/rollup-build-target.mjs +++ b/utils/rollup-build-target.mjs @@ -1,283 +1,15 @@ -// official package plugins -import resolve from '@rollup/plugin-node-resolve'; -import strip from '@rollup/plugin-strip'; -import swcPlugin from '@rollup/plugin-swc'; - -// unofficial package plugins import dts from 'rollup-plugin-dts'; -import jscc from 'rollup-plugin-jscc'; -import { visualizer } from 'rollup-plugin-visualizer'; // eslint-disable-line import/no-unresolved -// custom plugins -import { shaderChunks } from './plugins/rollup-shader-chunks.mjs'; -import { engineLayerImportValidation } from './plugins/rollup-import-validation.mjs'; -import { spacesToTabs } from './plugins/rollup-spaces-to-tabs.mjs'; -import { dynamicImportLegacyBrowserSupport, dynamicImportBundlerSuppress } from './plugins/rollup-dynamic.mjs'; import { runTsc } from './plugins/rollup-run-tsc.mjs'; import { typesFixup } from './plugins/rollup-types-fixup.mjs'; -import { version, revision } from './rollup-version-revision.mjs'; -import { getBanner } from './rollup-get-banner.mjs'; -import { swcOptions } from './rollup-swc-options.mjs'; - -import { dirname, resolve as pathResolve } from 'path'; -import { fileURLToPath } from 'url'; - -/** @import { RollupOptions, OutputOptions } from 'rollup' */ - -// Find path to the repo root -// @ts-ignore import.meta not allowed by tsconfig module:es6, but it works -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); -const rootDir = pathResolve(__dirname, '..'); - - -const STRIP_FUNCTIONS = [ - 'Debug.assert', - 'Debug.assertDeprecated', - 'Debug.assertDestroyed', - 'Debug.call', - 'Debug.deprecated', - 'Debug.warn', - 'Debug.warnOnce', - 'Debug.error', - 'Debug.errorOnce', - 'Debug.log', - 'Debug.logOnce', - 'Debug.removed', - 'Debug.trace', - 'DebugHelper.setName', - 'DebugHelper.setLabel', - 'DebugHelper.setDestroyed', - 'DebugGraphics.toString', - 'DebugGraphics.clearGpuMarkers', - 'DebugGraphics.pushGpuMarker', - 'DebugGraphics.popGpuMarker', - 'WebgpuDebug.validate', - 'WebgpuDebug.memory', - 'WebgpuDebug.internal', - 'WebgpuDebug.end', - 'WebgpuDebug.endShader', - 'WorldClustersDebug.render' -]; - -const BANNER = { - debug: ' (DEBUG)', - release: ' (RELEASE)', - profiler: ' (PROFILE)', - min: ' (RELEASE)' -}; - -const OUT_PREFIX = { - debug: 'playcanvas.dbg', - release: 'playcanvas', - profiler: 'playcanvas.prf', - min: 'playcanvas.min' -}; - -const HISTORY = new Map(); - -/** - * @param {'debug'|'release'|'profiler'} buildType - The build type. - * @returns {object} - The JSCC options. - */ -function getJSCCOptions(buildType) { - const options = { - debug: { - values: { - _CURRENT_SDK_VERSION: version, - _CURRENT_SDK_REVISION: revision, - _DEBUG: 1, - _PROFILER: 1 - }, - asloader: false, - keepLines: true - }, - release: { - values: { - _CURRENT_SDK_VERSION: version, - _CURRENT_SDK_REVISION: revision - }, - asloader: false - }, - profiler: { - values: { - _CURRENT_SDK_VERSION: version, - _CURRENT_SDK_REVISION: revision, - _PROFILER: 1 - }, - asloader: false - } - }; - return options[buildType]; -} - -/** - * @param {string} type - The type of the output (e.g., 'umd', 'es'). - * @returns {OutputOptions['plugins']} - The output plugins. - */ -function getOutPlugins(type) { - const plugins = []; - - if (process.env.treemap) { - plugins.push(visualizer({ - filename: `treemap.${type}.html`, - brotliSize: true, - gzipSize: true - })); - } - - if (process.env.treenet) { - plugins.push(visualizer({ - filename: `treenet.${type}.html`, - template: 'network' - })); - } - - if (process.env.treesun) { - plugins.push(visualizer({ - filename: `treesun.${type}.html`, - template: 'sunburst' - })); - } - - if (process.env.treeflame) { - plugins.push(visualizer({ - filename: `treeflame.${type}.html`, - template: 'flamegraph' - })); - } - - return plugins; -} - -/** - * Build rollup options for JS (bundled and unbundled). - * - * For faster subsequent builds, the unbundled and release builds are cached in the HISTORY map to - * be used for bundled and minified builds. They are stored in the HISTORY map with the key: - * `--`. - * - * @param {object} options - The build target options. - * @param {'umd'|'esm'} options.moduleFormat - The module format. - * @param {'debug'|'release'|'profiler'|'min'} options.buildType - The build type. - * @param {'unbundled'|'bundled'} [options.bundleState] - The bundle state. - * @param {string} [options.input] - Only used for examples to change it to `../src/index.js`. - * @param {string} [options.dir] - Only used for examples to change the output location. - * @returns {RollupOptions[]} Rollup targets. - */ -function buildJSOptions({ - moduleFormat, - buildType, - bundleState, - input = 'src/index.js', - dir = 'build' -}) { - const isUMD = moduleFormat === 'umd'; - const isDebug = buildType === 'debug'; - const isMin = buildType === 'min'; - const bundled = isUMD || isMin || bundleState === 'bundled'; - - const prefix = `${OUT_PREFIX[buildType]}`; - const file = `${prefix}${isUMD ? '.js' : '.mjs'}`; - - const targets = []; - - // bundle from unbundled - if (bundled && HISTORY.has(`${buildType}-${moduleFormat}-false`)) { - const unbundled = HISTORY.get(`${buildType}-${moduleFormat}-false`); - - /** - * @type {RollupOptions} - */ - const target = { - input: `${unbundled.output.dir}/src/index.js`, - output: { - banner: getBanner(BANNER[buildType]), - format: 'es', - indent: '\t', - sourcemap: isDebug && 'inline', - name: 'pc', - preserveModules: false, - file: `${dir}/${prefix}.mjs` - } - }; - - HISTORY.set(`${buildType}-${moduleFormat}-true`, target); - targets.push(target); - - return targets; - } - - // minify from release build - if (isMin && HISTORY.has(`release-${moduleFormat}-true`)) { - const release = HISTORY.get(`release-${moduleFormat}-true`); - - /** - * @type {RollupOptions} - */ - const target = { - input: release.output.file, - plugins: [ - swcPlugin({ swc: swcOptions(isDebug, isMin) }) - ], - output: { - banner: isUMD ? getBanner(BANNER[buildType]) : undefined, - file: `${dir}/${file}` - }, - context: isUMD ? 'this' : undefined - }; - - HISTORY.set(`${buildType}-${moduleFormat}-${bundled}`, target); - targets.push(target); - - return targets; - } - - /** - * @type {RollupOptions} - */ - const target = { - input, - output: { - banner: bundled ? getBanner(BANNER[buildType]) : undefined, - plugins: buildType === 'release' ? getOutPlugins(isUMD ? 'umd' : 'es') : undefined, - format: isUMD ? 'umd' : 'es', - indent: '\t', - sourcemap: bundled && isDebug && 'inline', - name: 'pc', - preserveModules: !bundled, - preserveModulesRoot: !bundled ? rootDir : undefined, - file: bundled ? `${dir}/${file}` : undefined, - dir: !bundled ? `${dir}/${prefix}` : undefined, - entryFileNames: chunkInfo => `${chunkInfo.name.replace(/node_modules/g, 'modules')}.js` - }, - plugins: [ - resolve(), - jscc(getJSCCOptions(isMin ? 'release' : buildType)), - isUMD ? dynamicImportLegacyBrowserSupport() : undefined, - !isDebug ? shaderChunks() : undefined, - isDebug ? engineLayerImportValidation(input) : undefined, - !isDebug ? strip({ functions: STRIP_FUNCTIONS }) : undefined, - swcPlugin({ swc: swcOptions(isDebug, isMin) }), - !isUMD ? dynamicImportBundlerSuppress() : undefined, - !isDebug ? spacesToTabs() : undefined - ] - }; - - HISTORY.set(`${buildType}-${moduleFormat}-${bundled}`, target); - targets.push(target); - - return targets; -} - /** * Build rollup options for TypeScript definitions. * * @param {object} options - The build target options. * @param {string} [options.root] - The root directory for finding the TypeScript definitions. * @param {string} [options.dir] - The output directory for the TypeScript definitions. - * @returns {RollupOptions} Rollup targets. + * @returns {import('rollup').RollupOptions} Rollup targets. */ function buildTypesOption({ root = '.', @@ -301,4 +33,4 @@ function buildTypesOption({ }; } -export { buildJSOptions, buildTypesOption }; +export { buildTypesOption }; diff --git a/utils/rollup-swc-options.mjs b/utils/rollup-swc-options.mjs deleted file mode 100644 index 5aa24acef0f..00000000000 --- a/utils/rollup-swc-options.mjs +++ /dev/null @@ -1,33 +0,0 @@ -/** @typedef {import('@swc/core').Config} SWCOptions */ - -/** - * The options for swc(...) plugin. - * - * @param {boolean} isDebug - Whether the build is for debug. - * @param {boolean} minify - Whether to minify. - * @returns {SWCOptions} The swc options. - */ -function swcOptions(isDebug, minify) { - - return { - minify, - jsc: { - target: 'es2020', - minify: { - format: { - comments: !isDebug || minify ? 'some' : 'all' - }, - mangle: minify, - compress: (!isDebug && minify) ? { - drop_console: true, - pure_funcs: [] - } : undefined - }, - externalHelpers: false, - loose: true - } - }; - -} - -export { swcOptions };