From 74ae7c8c309e38c47b14e214f2515d6129884d4f Mon Sep 17 00:00:00 2001 From: Ryan Carniato Date: Wed, 15 Jul 2026 13:35:29 -0700 Subject: [PATCH 1/5] ci: track tree-shaken scenario sizes per PR with size-limit (#2883) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five import-cost scenarios (signals floor / +createStore / +isPending, latest; the render+signal simple-app floor; a representative CSR app) with ~5% headroom limits as the tree-shaking regression gate — a re-coupled feature module costs hundreds of bytes against that headroom. The simple-app ceiling is pinned at 10 KB (brotli) deliberately. The size-limit action comments base-vs-head deltas on every PR; the retained-module-graph test in solid-signals stays the precise which-module diagnostic. Co-Authored-By: Claude Fable 5 --- .github/workflows/size.yml | 32 +++ .size-limit.json | 30 +++ package.json | 9 +- pnpm-lock.yaml | 403 ++++++++++++++++++++++++++++++++--- size-fixtures/csr-app.js | 11 + size-fixtures/lazy-page.js | 1 + size-fixtures/minimal-app.js | 11 + 7 files changed, 464 insertions(+), 33 deletions(-) create mode 100644 .github/workflows/size.yml create mode 100644 .size-limit.json create mode 100644 size-fixtures/csr-app.js create mode 100644 size-fixtures/lazy-page.js create mode 100644 size-fixtures/minimal-app.js diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml new file mode 100644 index 000000000..f4e3256ac --- /dev/null +++ b/.github/workflows/size.yml @@ -0,0 +1,32 @@ +name: Size + +# Tracks tree-shaken scenario costs per PR (#2883). The .size-limit.json +# entries are import-cost scenarios, not file sizes: the limits are the strict +# gate for tree-shaking regressions (a re-coupled feature module shows up as +# hundreds of bytes against ~5% headroom), and the PR comment shows the +# base-vs-head delta per scenario. The retained-module-graph assertions in +# packages/solid-signals/tests/treeshake.test.ts remain the precise +# which-module-re-coupled diagnostic; this is the trend tracker on top. +on: + pull_request: + branches: [main, next] + +permissions: + contents: read + pull-requests: write + +jobs: + size: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: pnpm + - uses: andresz1/size-limit-action@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + package_manager: pnpm + build_script: build diff --git a/.size-limit.json b/.size-limit.json new file mode 100644 index 000000000..db72ee27e --- /dev/null +++ b/.size-limit.json @@ -0,0 +1,30 @@ +[ + { + "name": "signals: core floor (createSignal/Memo/Effect/Root/flush)", + "path": "packages/solid-signals/dist/prod/index.js", + "import": "{ createSignal, createMemo, createEffect, createRoot, flush }", + "limit": "7.1 KB" + }, + { + "name": "signals: + createStore", + "path": "packages/solid-signals/dist/prod/index.js", + "import": "{ createSignal, createMemo, createEffect, createRoot, flush, createStore }", + "limit": "11.6 KB" + }, + { + "name": "signals: + isPending/latest", + "path": "packages/solid-signals/dist/prod/index.js", + "import": "{ createSignal, createMemo, createEffect, createRoot, flush, isPending, latest }", + "limit": "8.75 KB" + }, + { + "name": "app: render + one signal (the simple-app floor)", + "path": "size-fixtures/minimal-app.js", + "limit": "10 KB" + }, + { + "name": "app: CSR with Show/For/Loading/Errored/lazy", + "path": "size-fixtures/csr-app.js", + "limit": "12 KB" + } +] diff --git a/package.json b/package.json index ef8320f44..85ecab414 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "publish": "pnpm run build && pnpm run types && pnpm run release:only", "bump": "changeset add", "release:only": "changeset publish", - "format": "prettier --write --cache \"**/*.[tj]s?(x)\"" + "format": "prettier --write --cache \"**/*.[tj]s?(x)\"", + "size": "size-limit" }, "devDependencies": { "@babel/cli": "^7.18.9", @@ -38,11 +39,15 @@ "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-replace": "^5.0.2", + "@size-limit/preset-small-lib": "^12.1.0", + "@solidjs/signals": "workspace:*", + "@solidjs/web": "workspace:*", "@types/node": "^25.0.8", "@vitest/coverage-v8": "^4.1.6", "babel-plugin-transform-rename-import": "^2.3.0", "coveralls": "^3.1.1", "csstype": "^3.1.0", + "esbuild": "^0.28.1", "jsdom": "^25.0.1", "ncp": "^2.0.0", "npm-run-all2": "^8.0.4", @@ -53,6 +58,8 @@ "rollup-plugin-copy": "^3.4.0", "seroval": "~1.5.4", "simple-git-hooks": "^2.8.1", + "size-limit": "^12.1.0", + "solid-js": "workspace:*", "symlink-dir": "^5.0.1", "tsconfig-replace-paths": "^0.0.11", "turbo": "^2.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1273fbac2..94da7fad4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,15 @@ importers: '@rollup/plugin-replace': specifier: ^5.0.2 version: 5.0.7(rollup@4.59.0) + '@size-limit/preset-small-lib': + specifier: ^12.1.0 + version: 12.1.0(size-limit@12.1.0) + '@solidjs/signals': + specifier: workspace:* + version: link:packages/solid-signals + '@solidjs/web': + specifier: workspace:* + version: link:packages/solid-web '@types/node': specifier: ^25.0.8 version: 25.6.0 @@ -74,6 +83,9 @@ importers: csstype: specifier: ^3.1.0 version: 3.2.3 + esbuild: + specifier: ^0.28.1 + version: 0.28.1 jsdom: specifier: ^25.0.1 version: 25.0.1 @@ -104,6 +116,12 @@ importers: simple-git-hooks: specifier: ^2.8.1 version: 2.13.1 + size-limit: + specifier: ^12.1.0 + version: 12.1.0 + solid-js: + specifier: workspace:* + version: link:packages/solid symlink-dir: specifier: ^5.0.1 version: 5.2.1 @@ -118,7 +136,7 @@ importers: version: 6.0.3 vite-plugin-solid: specifier: 3.0.0-next.4 - version: 3.0.0-next.4(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) + version: 3.0.0-next.4(@solidjs/web@packages+solid-web)(solid-js@packages+solid)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) vitest: specifier: ^4.1.6 version: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) @@ -410,7 +428,7 @@ importers: version: 7.3.3(@types/node@25.6.0)(terser@5.49.0) vitest: specifier: ^4.1.6 - version: 4.1.6(@types/node@25.6.0)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) + version: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) packages/solid-universal: devDependencies: @@ -1119,156 +1137,312 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.27.7': resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.27.7': resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.27.7': resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.27.7': resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.27.7': resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.27.7': resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.27.7': resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.27.7': resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.27.7': resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.27.7': resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.27.7': resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.27.7': resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.27.7': resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.27.7': resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.27.7': resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.27.7': resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.27.7': resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.27.7': resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.27.7': resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.27.7': resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.27.7': resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.27.7': resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.27.7': resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.27.7': resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.27.7': resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@ianvs/prettier-plugin-sort-imports@4.7.1': resolution: {integrity: sha512-jmTNYGlg95tlsoG3JLCcuC4BrFELJtLirLAkQW/71lXSyOhVt/Xj7xWbbGcuVbNq1gwWgSyMrPjJc9Z30hynVw==} peerDependencies: @@ -1562,6 +1736,23 @@ packages: cpu: [x64] os: [win32] + '@size-limit/esbuild@12.1.0': + resolution: {integrity: sha512-Um6MVrX+05kIxI4+zk0ZByG9dA/Th1f+sfGc571D95BnCPc90/pl2+2OdsQuOyoWEbeAMqfcTKo0v07i+E65Vw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + size-limit: 12.1.0 + + '@size-limit/file@12.1.0': + resolution: {integrity: sha512-eGwDcIufnNnvJRzv3liDOn6MAOGgmOTUdpeGQ2KuRTlgIgO54AJH1ilvktlJc6PIjNfwpYY0dOGyap1QgM1swQ==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + size-limit: 12.1.0 + + '@size-limit/preset-small-lib@12.1.0': + resolution: {integrity: sha512-TVVQ/iuHbaGtHJrjur5s4XKYEyGk0nIwUAqhuzhKPbTyV9nYOH/laDelQ4vg3cGmm8sayRx998wxEdnwM/Yewg==} + peerDependencies: + size-limit: 12.1.0 + '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -1831,6 +2022,10 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} + bytes-iec@3.1.1: + resolution: {integrity: sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==} + engines: {node: '>= 0.8'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -2060,6 +2255,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -2497,6 +2697,10 @@ packages: resolution: {integrity: sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==} hasBin: true + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -2655,6 +2859,14 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@5.1.16: + resolution: {integrity: sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==} + engines: {node: ^18 || >=20} + hasBin: true + + nanospinner@1.2.2: + resolution: {integrity: sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==} + ncp@2.0.0: resolution: {integrity: sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==} hasBin: true @@ -3056,6 +3268,16 @@ packages: resolution: {integrity: sha512-WszCLXwT4h2k1ufIXAgsbiTOazqqevFCIncOuUBZJ91DdvWcC5+OFkluWRQPrcuSYd8fjq+o2y1QfWqYMoAToQ==} hasBin: true + size-limit@12.1.0: + resolution: {integrity: sha512-VnDS2fycANrJFVPQwjaD+h+hkISY7EB3LsPsYWje4lBCjQwwsZLxjwwRwVJKHrcj2ZqyG+DdXykWm9mbZklZrw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + jiti: ^2.0.0 + peerDependenciesMeta: + jiti: + optional: true + skip-regex@1.0.2: resolution: {integrity: sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==} engines: {node: '>=4.2'} @@ -4423,81 +4645,159 @@ snapshots: '@esbuild/aix-ppc64@0.27.7': optional: true + '@esbuild/aix-ppc64@0.28.1': + optional: true + '@esbuild/android-arm64@0.27.7': optional: true + '@esbuild/android-arm64@0.28.1': + optional: true + '@esbuild/android-arm@0.27.7': optional: true + '@esbuild/android-arm@0.28.1': + optional: true + '@esbuild/android-x64@0.27.7': optional: true + '@esbuild/android-x64@0.28.1': + optional: true + '@esbuild/darwin-arm64@0.27.7': optional: true + '@esbuild/darwin-arm64@0.28.1': + optional: true + '@esbuild/darwin-x64@0.27.7': optional: true + '@esbuild/darwin-x64@0.28.1': + optional: true + '@esbuild/freebsd-arm64@0.27.7': optional: true + '@esbuild/freebsd-arm64@0.28.1': + optional: true + '@esbuild/freebsd-x64@0.27.7': optional: true + '@esbuild/freebsd-x64@0.28.1': + optional: true + '@esbuild/linux-arm64@0.27.7': optional: true + '@esbuild/linux-arm64@0.28.1': + optional: true + '@esbuild/linux-arm@0.27.7': optional: true + '@esbuild/linux-arm@0.28.1': + optional: true + '@esbuild/linux-ia32@0.27.7': optional: true + '@esbuild/linux-ia32@0.28.1': + optional: true + '@esbuild/linux-loong64@0.27.7': optional: true + '@esbuild/linux-loong64@0.28.1': + optional: true + '@esbuild/linux-mips64el@0.27.7': optional: true + '@esbuild/linux-mips64el@0.28.1': + optional: true + '@esbuild/linux-ppc64@0.27.7': optional: true + '@esbuild/linux-ppc64@0.28.1': + optional: true + '@esbuild/linux-riscv64@0.27.7': optional: true + '@esbuild/linux-riscv64@0.28.1': + optional: true + '@esbuild/linux-s390x@0.27.7': optional: true + '@esbuild/linux-s390x@0.28.1': + optional: true + '@esbuild/linux-x64@0.27.7': optional: true + '@esbuild/linux-x64@0.28.1': + optional: true + '@esbuild/netbsd-arm64@0.27.7': optional: true + '@esbuild/netbsd-arm64@0.28.1': + optional: true + '@esbuild/netbsd-x64@0.27.7': optional: true + '@esbuild/netbsd-x64@0.28.1': + optional: true + '@esbuild/openbsd-arm64@0.27.7': optional: true + '@esbuild/openbsd-arm64@0.28.1': + optional: true + '@esbuild/openbsd-x64@0.27.7': optional: true + '@esbuild/openbsd-x64@0.28.1': + optional: true + '@esbuild/openharmony-arm64@0.27.7': optional: true + '@esbuild/openharmony-arm64@0.28.1': + optional: true + '@esbuild/sunos-x64@0.27.7': optional: true + '@esbuild/sunos-x64@0.28.1': + optional: true + '@esbuild/win32-arm64@0.27.7': optional: true + '@esbuild/win32-arm64@0.28.1': + optional: true + '@esbuild/win32-ia32@0.27.7': optional: true + '@esbuild/win32-ia32@0.28.1': + optional: true + '@esbuild/win32-x64@0.27.7': optional: true + '@esbuild/win32-x64@0.28.1': + optional: true + '@ianvs/prettier-plugin-sort-imports@4.7.1(prettier@3.8.1)': dependencies: '@babel/generator': 7.29.1 @@ -4769,6 +5069,22 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true + '@size-limit/esbuild@12.1.0(size-limit@12.1.0)': + dependencies: + esbuild: 0.28.1 + nanoid: 5.1.16 + size-limit: 12.1.0 + + '@size-limit/file@12.1.0(size-limit@12.1.0)': + dependencies: + size-limit: 12.1.0 + + '@size-limit/preset-small-lib@12.1.0(size-limit@12.1.0)': + dependencies: + '@size-limit/esbuild': 12.1.0(size-limit@12.1.0) + '@size-limit/file': 12.1.0(size-limit@12.1.0) + size-limit: 12.1.0 + '@standard-schema/spec@1.1.0': {} '@types/babel__core@7.20.5': @@ -5085,6 +5401,8 @@ snapshots: builtin-modules@3.3.0: {} + bytes-iec@3.1.1: {} + bytes@3.1.2: {} call-bind-apply-helpers@1.0.2: @@ -5300,6 +5618,35 @@ snapshots: '@esbuild/win32-ia32': 0.27.7 '@esbuild/win32-x64': 0.27.7 + esbuild@0.28.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -5798,6 +6145,8 @@ snapshots: lcov-parse@1.0.0: {} + lilconfig@3.1.3: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -5927,6 +6276,12 @@ snapshots: nanoid@3.3.11: {} + nanoid@5.1.16: {} + + nanospinner@1.2.2: + dependencies: + picocolors: 1.1.1 + ncp@2.0.0: {} negotiator@0.6.3: {} @@ -6347,16 +6702,25 @@ snapshots: simple-git-hooks@2.13.1: {} + size-limit@12.1.0: + dependencies: + bytes-iec: 3.1.1 + lilconfig: 3.1.3 + nanospinner: 1.2.2 + picocolors: 1.1.1 + tinyglobby: 0.2.16 + skip-regex@1.0.2: {} slash@2.0.0: {} slash@3.0.0: {} - solid-refresh@0.8.0-next.4: + solid-refresh@0.8.0-next.4(solid-js@packages+solid): dependencies: '@babel/generator': 7.29.1 '@babel/types': 7.29.0 + solid-js: link:packages/solid source-map-js@1.2.1: {} @@ -6578,13 +6942,15 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite-plugin-solid@3.0.0-next.4(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): + vite-plugin-solid@3.0.0-next.4(@solidjs/web@packages+solid-web)(solid-js@packages+solid)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): dependencies: '@babel/core': 7.29.0 + '@solidjs/web': link:packages/solid-web '@types/babel__core': 7.20.5 babel-preset-solid: link:packages/babel-preset-solid merge-anything: 5.1.7 - solid-refresh: 0.8.0-next.4 + solid-js: link:packages/solid + solid-refresh: 0.8.0-next.4(solid-js@packages+solid) vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) vitefu: 1.1.2(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) transitivePeerDependencies: @@ -6636,33 +7002,6 @@ snapshots: transitivePeerDependencies: - msw - vitest@4.1.6(@types/node@25.6.0)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): - dependencies: - '@vitest/expect': 4.1.6 - '@vitest/mocker': 4.1.6(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) - '@vitest/pretty-format': 4.1.6 - '@vitest/runner': 4.1.6 - '@vitest/snapshot': 4.1.6 - '@vitest/spy': 4.1.6 - '@vitest/utils': 4.1.6 - es-module-lexer: 2.1.0 - expect-type: 1.3.0 - magic-string: 0.30.21 - obug: 2.1.1 - pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.1.0 - tinybench: 2.9.0 - tinyexec: 1.1.2 - tinyglobby: 0.2.16 - tinyrainbow: 3.1.0 - vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 25.6.0 - transitivePeerDependencies: - - msw - w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 diff --git a/size-fixtures/csr-app.js b/size-fixtures/csr-app.js new file mode 100644 index 000000000..2c68f15cd --- /dev/null +++ b/size-fixtures/csr-app.js @@ -0,0 +1,11 @@ +// A representative CSR app surface: flow components, boundaries, lazy. +import { render, Show, For, Loading, Errored } from "@solidjs/web"; +import { createSignal, createMemo, lazy } from "solid-js"; + +const [n, setN] = createSignal(0); +const Page = lazy(() => import("./lazy-page.js")); +render(() => { + const d = createMemo(() => n() + 1); + setN(1); + return [d(), Show, For, Loading, Errored, Page]; +}, document.body); diff --git a/size-fixtures/lazy-page.js b/size-fixtures/lazy-page.js new file mode 100644 index 000000000..0a818fdf3 --- /dev/null +++ b/size-fixtures/lazy-page.js @@ -0,0 +1 @@ +export default () => "page"; diff --git a/size-fixtures/minimal-app.js b/size-fixtures/minimal-app.js new file mode 100644 index 000000000..983c1827a --- /dev/null +++ b/size-fixtures/minimal-app.js @@ -0,0 +1,11 @@ +// The "simple app" floor: render + one signal. Tracks the tree-shaken cost a +// hello-world CSR app ships (#2883). +import { render } from "@solidjs/web"; +import { createSignal } from "solid-js"; + +const [count, setCount] = createSignal(0); +render(() => { + const el = document.createElement("button"); + el.onclick = () => setCount(count() + 1); + return el; +}, document.getElementById("app")); From 48279b1c94688981d002cc3a6a693093f133ea79 Mon Sep 17 00:00:00 2001 From: Ryan Carniato Date: Wed, 15 Jul 2026 13:51:34 -0700 Subject: [PATCH 2/5] ci: split size workflow into a self-contained gate and best-effort delta comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The size-limit action compares against the base branch, which fails on any PR whose base lacks the size-limit setup (including this bootstrap PR) with 'Unexpected end of JSON input'. The hard gate is now its own job — install, build, pnpm size on the head only — and the base-vs-head comment job is continue-on-error, so it informs when it can and never blocks. Co-Authored-By: Claude Fable 5 --- .github/workflows/size.yml | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml index f4e3256ac..ad23b5353 100644 --- a/.github/workflows/size.yml +++ b/.github/workflows/size.yml @@ -3,10 +3,10 @@ name: Size # Tracks tree-shaken scenario costs per PR (#2883). The .size-limit.json # entries are import-cost scenarios, not file sizes: the limits are the strict # gate for tree-shaking regressions (a re-coupled feature module shows up as -# hundreds of bytes against ~5% headroom), and the PR comment shows the -# base-vs-head delta per scenario. The retained-module-graph assertions in -# packages/solid-signals/tests/treeshake.test.ts remain the precise -# which-module-re-coupled diagnostic; this is the trend tracker on top. +# hundreds of bytes against ~5% headroom). The retained-module-graph +# assertions in packages/solid-signals/tests/treeshake.test.ts remain the +# precise which-module-re-coupled diagnostic; this is the ceiling gate and +# trend tracker on top. on: pull_request: branches: [main, next] @@ -16,8 +16,27 @@ permissions: pull-requests: write jobs: - size: + # The hard gate: self-contained on the PR head, fails when any scenario + # exceeds its limit. Never depends on the base branch. + check: runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm build + - run: pnpm size + + # Best-effort base-vs-head delta comment. Requires the base branch to also + # carry the size-limit setup, so it is informational and never blocks: + # continue-on-error keeps bootstrap PRs (and any action hiccup) green. + compare: + runs-on: ubuntu-latest + continue-on-error: true steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 @@ -26,6 +45,7 @@ jobs: node-version-file: ".nvmrc" cache: pnpm - uses: andresz1/size-limit-action@v1 + continue-on-error: true with: github_token: ${{ secrets.GITHUB_TOKEN }} package_manager: pnpm From 4752d702f11966993908f8b24c40f68816c41855 Mon Sep 17 00:00:00 2001 From: Ryan Carniato Date: Wed, 15 Jul 2026 14:10:40 -0700 Subject: [PATCH 3/5] ci(size): resolve fixtures via esbuild aliases, not root workspace deps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding solid-js/@solidjs/* as root devDeps re-keyed pnpm's peer graph (vitest and vite-plugin-solid instances gained new peer contexts), relocating the benchmark harness's physical dependencies — which CodSpeed reports as instruction-count regressions despite zero code changes. Aliases in .size-limit.js point bare specifiers at the built browser-prod artifacts instead; the lockfile now only adds size-limit's own isolated tree. Same measured numbers on every scenario. Co-Authored-By: Claude Fable 5 --- .size-limit.js | 47 +++++++++++++++++++++++++ .size-limit.json | 30 ---------------- package.json | 3 -- pnpm-lock.yaml | 89 ++++++++++++++++++++++++++++++++++-------------- 4 files changed, 110 insertions(+), 59 deletions(-) create mode 100644 .size-limit.js delete mode 100644 .size-limit.json diff --git a/.size-limit.js b/.size-limit.js new file mode 100644 index 000000000..bc44951fc --- /dev/null +++ b/.size-limit.js @@ -0,0 +1,47 @@ +// Import-cost scenarios for #2883. Bare specifiers resolve via esbuild +// aliases to the built browser-prod artifacts rather than root workspace +// devDeps: adding solid-js/@solidjs/* to the root package.json re-keys +// pnpm's peer graph (vitest/vite-plugin-solid instances), which relocates +// the benchmark harness and shows up as phantom CodSpeed regressions. +const alias = { + "solid-js": "./packages/solid/dist/solid.js", + "@solidjs/web": "./packages/solid-web/dist/web.js", + "@solidjs/signals": "./packages/solid-signals/dist/prod/index.js" +}; +const modifyEsbuildConfig = config => ({ ...config, alias }); + +module.exports = [ + { + name: "signals: core floor (createSignal/Memo/Effect/Root/flush)", + path: "packages/solid-signals/dist/prod/index.js", + import: "{ createSignal, createMemo, createEffect, createRoot, flush }", + limit: "7.1 KB", + modifyEsbuildConfig + }, + { + name: "signals: + createStore", + path: "packages/solid-signals/dist/prod/index.js", + import: "{ createSignal, createMemo, createEffect, createRoot, flush, createStore }", + limit: "11.6 KB", + modifyEsbuildConfig + }, + { + name: "signals: + isPending/latest", + path: "packages/solid-signals/dist/prod/index.js", + import: "{ createSignal, createMemo, createEffect, createRoot, flush, isPending, latest }", + limit: "8.75 KB", + modifyEsbuildConfig + }, + { + name: "app: render + one signal (the simple-app floor)", + path: "size-fixtures/minimal-app.js", + limit: "10 KB", + modifyEsbuildConfig + }, + { + name: "app: CSR with Show/For/Loading/Errored/lazy", + path: "size-fixtures/csr-app.js", + limit: "12 KB", + modifyEsbuildConfig + } +]; diff --git a/.size-limit.json b/.size-limit.json deleted file mode 100644 index db72ee27e..000000000 --- a/.size-limit.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "name": "signals: core floor (createSignal/Memo/Effect/Root/flush)", - "path": "packages/solid-signals/dist/prod/index.js", - "import": "{ createSignal, createMemo, createEffect, createRoot, flush }", - "limit": "7.1 KB" - }, - { - "name": "signals: + createStore", - "path": "packages/solid-signals/dist/prod/index.js", - "import": "{ createSignal, createMemo, createEffect, createRoot, flush, createStore }", - "limit": "11.6 KB" - }, - { - "name": "signals: + isPending/latest", - "path": "packages/solid-signals/dist/prod/index.js", - "import": "{ createSignal, createMemo, createEffect, createRoot, flush, isPending, latest }", - "limit": "8.75 KB" - }, - { - "name": "app: render + one signal (the simple-app floor)", - "path": "size-fixtures/minimal-app.js", - "limit": "10 KB" - }, - { - "name": "app: CSR with Show/For/Loading/Errored/lazy", - "path": "size-fixtures/csr-app.js", - "limit": "12 KB" - } -] diff --git a/package.json b/package.json index 85ecab414..45b8e4cd0 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,6 @@ "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-replace": "^5.0.2", "@size-limit/preset-small-lib": "^12.1.0", - "@solidjs/signals": "workspace:*", - "@solidjs/web": "workspace:*", "@types/node": "^25.0.8", "@vitest/coverage-v8": "^4.1.6", "babel-plugin-transform-rename-import": "^2.3.0", @@ -59,7 +57,6 @@ "seroval": "~1.5.4", "simple-git-hooks": "^2.8.1", "size-limit": "^12.1.0", - "solid-js": "workspace:*", "symlink-dir": "^5.0.1", "tsconfig-replace-paths": "^0.0.11", "turbo": "^2.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94da7fad4..d619fd27f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,7 +31,7 @@ importers: version: 2.29.8(@types/node@25.6.0) '@codspeed/vitest-plugin': specifier: ^5.4.0 - version: 5.4.0(tinybench@2.9.0)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0))(vitest@4.1.6) + version: 5.4.0(tinybench@2.9.0)(vite@7.3.3(@types/node@25.6.0))(vitest@4.1.6) '@dom-expressions/babel-plugin-jsx': specifier: 0.50.0-next.21 version: 0.50.0-next.21(@babel/core@7.29.0) @@ -62,12 +62,6 @@ importers: '@size-limit/preset-small-lib': specifier: ^12.1.0 version: 12.1.0(size-limit@12.1.0) - '@solidjs/signals': - specifier: workspace:* - version: link:packages/solid-signals - '@solidjs/web': - specifier: workspace:* - version: link:packages/solid-web '@types/node': specifier: ^25.0.8 version: 25.6.0 @@ -119,9 +113,6 @@ importers: size-limit: specifier: ^12.1.0 version: 12.1.0 - solid-js: - specifier: workspace:* - version: link:packages/solid symlink-dir: specifier: ^5.0.1 version: 5.2.1 @@ -136,10 +127,10 @@ importers: version: 6.0.3 vite-plugin-solid: specifier: 3.0.0-next.4 - version: 3.0.0-next.4(@solidjs/web@packages+solid-web)(solid-js@packages+solid)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) + version: 3.0.0-next.4(vite@7.3.3(@types/node@25.6.0)) vitest: specifier: ^4.1.6 - version: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) + version: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)) examples/migrating-element: devDependencies: @@ -4592,12 +4583,12 @@ snapshots: transitivePeerDependencies: - debug - '@codspeed/vitest-plugin@5.4.0(tinybench@2.9.0)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0))(vitest@4.1.6)': + '@codspeed/vitest-plugin@5.4.0(tinybench@2.9.0)(vite@7.3.3(@types/node@25.6.0))(vitest@4.1.6)': dependencies: '@codspeed/core': 5.4.0 tinybench: 2.9.0 - vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) - vitest: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) + vite: 7.3.3(@types/node@25.6.0) + vitest: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)) transitivePeerDependencies: - debug @@ -5193,7 +5184,7 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) + vitest: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)) '@vitest/expect@4.1.6': dependencies: @@ -5212,6 +5203,14 @@ snapshots: optionalDependencies: vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) + '@vitest/mocker@4.1.6(vite@7.3.3(@types/node@25.6.0))': + dependencies: + '@vitest/spy': 4.1.6 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.3(@types/node@25.6.0) + '@vitest/pretty-format@4.1.6': dependencies: tinyrainbow: 3.1.0 @@ -6716,11 +6715,10 @@ snapshots: slash@3.0.0: {} - solid-refresh@0.8.0-next.4(solid-js@packages+solid): + solid-refresh@0.8.0-next.4: dependencies: '@babel/generator': 7.29.1 '@babel/types': 7.29.0 - solid-js: link:packages/solid source-map-js@1.2.1: {} @@ -6942,20 +6940,30 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite-plugin-solid@3.0.0-next.4(@solidjs/web@packages+solid-web)(solid-js@packages+solid)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): + vite-plugin-solid@3.0.0-next.4(vite@7.3.3(@types/node@25.6.0)): dependencies: '@babel/core': 7.29.0 - '@solidjs/web': link:packages/solid-web '@types/babel__core': 7.20.5 babel-preset-solid: link:packages/babel-preset-solid merge-anything: 5.1.7 - solid-js: link:packages/solid - solid-refresh: 0.8.0-next.4(solid-js@packages+solid) - vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) - vitefu: 1.1.2(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) + solid-refresh: 0.8.0-next.4 + vite: 7.3.3(@types/node@25.6.0) + vitefu: 1.1.2(vite@7.3.3(@types/node@25.6.0)) transitivePeerDependencies: - supports-color + vite@7.3.3(@types/node@25.6.0): + dependencies: + esbuild: 0.27.7 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.6 + rollup: 4.59.0 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 25.6.0 + fsevents: 2.3.3 + vite@7.3.3(@types/node@25.6.0)(terser@5.49.0): dependencies: esbuild: 0.27.7 @@ -6969,9 +6977,9 @@ snapshots: fsevents: 2.3.3 terser: 5.49.0 - vitefu@1.1.2(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): + vitefu@1.1.2(vite@7.3.3(@types/node@25.6.0)): optionalDependencies: - vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) + vite: 7.3.3(@types/node@25.6.0) vitest@4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): dependencies: @@ -7002,6 +7010,35 @@ snapshots: transitivePeerDependencies: - msw + vitest@4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)): + dependencies: + '@vitest/expect': 4.1.6 + '@vitest/mocker': 4.1.6(vite@7.3.3(@types/node@25.6.0)) + '@vitest/pretty-format': 4.1.6 + '@vitest/runner': 4.1.6 + '@vitest/snapshot': 4.1.6 + '@vitest/spy': 4.1.6 + '@vitest/utils': 4.1.6 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.1.2 + tinyglobby: 0.2.16 + tinyrainbow: 3.1.0 + vite: 7.3.3(@types/node@25.6.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.6.0 + '@vitest/coverage-v8': 4.1.6(vitest@4.1.6) + jsdom: 25.0.1 + transitivePeerDependencies: + - msw + w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 From 3dcacaaeeb60ad2e440d62ab29269f72a61c2e94 Mon Sep 17 00:00:00 2001 From: Ryan Carniato Date: Wed, 15 Jul 2026 14:12:28 -0700 Subject: [PATCH 4/5] ci(size): isolate size tooling in a standalone size/ package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Any change to the workspace dependency graph re-keys pnpm peer instances — removing the workspace devDeps still moved @codspeed/vitest-plugin and vite instance keys (vite's optional terser peer context) — and relocating the benchmark harness shows up as phantom CodSpeed regressions. size/ is now a plain npm package outside the pnpm workspace with its own lockfile; the root package.json and pnpm-lock.yaml are byte-identical to next. Fixtures resolve bare specifiers via esbuild aliases to the built browser-prod artifacts. Same measured numbers on every scenario. Co-Authored-By: Claude Fable 5 --- .github/workflows/size.yml | 27 +- package.json | 6 +- pnpm-lock.yaml | 408 +-------------- size/.gitignore | 1 + .size-limit.js => size/.size-limit.js | 27 +- {size-fixtures => size}/csr-app.js | 0 {size-fixtures => size}/lazy-page.js | 0 {size-fixtures => size}/minimal-app.js | 0 size/package-lock.json | 678 +++++++++++++++++++++++++ size/package.json | 13 + 10 files changed, 739 insertions(+), 421 deletions(-) create mode 100644 size/.gitignore rename .size-limit.js => size/.size-limit.js (52%) rename {size-fixtures => size}/csr-app.js (100%) rename {size-fixtures => size}/lazy-page.js (100%) rename {size-fixtures => size}/minimal-app.js (100%) create mode 100644 size/package-lock.json create mode 100644 size/package.json diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml index ad23b5353..2695dbb02 100644 --- a/.github/workflows/size.yml +++ b/.github/workflows/size.yml @@ -1,12 +1,13 @@ name: Size -# Tracks tree-shaken scenario costs per PR (#2883). The .size-limit.json -# entries are import-cost scenarios, not file sizes: the limits are the strict -# gate for tree-shaking regressions (a re-coupled feature module shows up as -# hundreds of bytes against ~5% headroom). The retained-module-graph -# assertions in packages/solid-signals/tests/treeshake.test.ts remain the -# precise which-module-re-coupled diagnostic; this is the ceiling gate and -# trend tracker on top. +# Tracks tree-shaken scenario costs per PR (#2883). The size/ directory is a +# standalone npm package OUTSIDE the pnpm workspace on purpose: adding its +# tooling to the workspace graph re-keys pnpm peer instances (vitest, +# @codspeed/vitest-plugin), which relocates the benchmark harness and shows +# up as phantom CodSpeed regressions. The limits in size/.size-limit.js are +# the strict tree-shaking gate; the retained-module-graph assertions in +# packages/solid-signals/tests/treeshake.test.ts stay the which-module +# diagnostic underneath. on: pull_request: branches: [main, next] @@ -29,11 +30,14 @@ jobs: cache: pnpm - run: pnpm install --frozen-lockfile - run: pnpm build - - run: pnpm size + - run: npm ci --no-audit --no-fund + working-directory: size + - run: npm run size + working-directory: size # Best-effort base-vs-head delta comment. Requires the base branch to also - # carry the size-limit setup, so it is informational and never blocks: - # continue-on-error keeps bootstrap PRs (and any action hiccup) green. + # carry size/, so it is informational and never blocks: continue-on-error + # keeps bootstrap PRs (and any action hiccup) green. compare: runs-on: ubuntu-latest continue-on-error: true @@ -48,5 +52,6 @@ jobs: continue-on-error: true with: github_token: ${{ secrets.GITHUB_TOKEN }} - package_manager: pnpm + package_manager: npm + directory: size build_script: build diff --git a/package.json b/package.json index 45b8e4cd0..ef8320f44 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,7 @@ "publish": "pnpm run build && pnpm run types && pnpm run release:only", "bump": "changeset add", "release:only": "changeset publish", - "format": "prettier --write --cache \"**/*.[tj]s?(x)\"", - "size": "size-limit" + "format": "prettier --write --cache \"**/*.[tj]s?(x)\"" }, "devDependencies": { "@babel/cli": "^7.18.9", @@ -39,13 +38,11 @@ "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-replace": "^5.0.2", - "@size-limit/preset-small-lib": "^12.1.0", "@types/node": "^25.0.8", "@vitest/coverage-v8": "^4.1.6", "babel-plugin-transform-rename-import": "^2.3.0", "coveralls": "^3.1.1", "csstype": "^3.1.0", - "esbuild": "^0.28.1", "jsdom": "^25.0.1", "ncp": "^2.0.0", "npm-run-all2": "^8.0.4", @@ -56,7 +53,6 @@ "rollup-plugin-copy": "^3.4.0", "seroval": "~1.5.4", "simple-git-hooks": "^2.8.1", - "size-limit": "^12.1.0", "symlink-dir": "^5.0.1", "tsconfig-replace-paths": "^0.0.11", "turbo": "^2.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d619fd27f..1273fbac2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,7 +31,7 @@ importers: version: 2.29.8(@types/node@25.6.0) '@codspeed/vitest-plugin': specifier: ^5.4.0 - version: 5.4.0(tinybench@2.9.0)(vite@7.3.3(@types/node@25.6.0))(vitest@4.1.6) + version: 5.4.0(tinybench@2.9.0)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0))(vitest@4.1.6) '@dom-expressions/babel-plugin-jsx': specifier: 0.50.0-next.21 version: 0.50.0-next.21(@babel/core@7.29.0) @@ -59,9 +59,6 @@ importers: '@rollup/plugin-replace': specifier: ^5.0.2 version: 5.0.7(rollup@4.59.0) - '@size-limit/preset-small-lib': - specifier: ^12.1.0 - version: 12.1.0(size-limit@12.1.0) '@types/node': specifier: ^25.0.8 version: 25.6.0 @@ -77,9 +74,6 @@ importers: csstype: specifier: ^3.1.0 version: 3.2.3 - esbuild: - specifier: ^0.28.1 - version: 0.28.1 jsdom: specifier: ^25.0.1 version: 25.0.1 @@ -110,9 +104,6 @@ importers: simple-git-hooks: specifier: ^2.8.1 version: 2.13.1 - size-limit: - specifier: ^12.1.0 - version: 12.1.0 symlink-dir: specifier: ^5.0.1 version: 5.2.1 @@ -127,10 +118,10 @@ importers: version: 6.0.3 vite-plugin-solid: specifier: 3.0.0-next.4 - version: 3.0.0-next.4(vite@7.3.3(@types/node@25.6.0)) + version: 3.0.0-next.4(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) vitest: specifier: ^4.1.6 - version: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)) + version: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) examples/migrating-element: devDependencies: @@ -419,7 +410,7 @@ importers: version: 7.3.3(@types/node@25.6.0)(terser@5.49.0) vitest: specifier: ^4.1.6 - version: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) + version: 4.1.6(@types/node@25.6.0)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) packages/solid-universal: devDependencies: @@ -1128,312 +1119,156 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.28.1': - resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/android-arm64@0.27.7': resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.28.1': - resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm@0.27.7': resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-arm@0.28.1': - resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-x64@0.27.7': resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.28.1': - resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/darwin-arm64@0.27.7': resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.28.1': - resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-x64@0.27.7': resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.28.1': - resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/freebsd-arm64@0.27.7': resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.28.1': - resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-x64@0.27.7': resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.28.1': - resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/linux-arm64@0.27.7': resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.28.1': - resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm@0.27.7': resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.28.1': - resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-ia32@0.27.7': resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.28.1': - resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-loong64@0.27.7': resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.28.1': - resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-mips64el@0.27.7': resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.28.1': - resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-ppc64@0.27.7': resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.28.1': - resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-riscv64@0.27.7': resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.28.1': - resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-s390x@0.27.7': resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.28.1': - resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-x64@0.27.7': resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.28.1': - resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/netbsd-arm64@0.27.7': resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.28.1': - resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-x64@0.27.7': resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.28.1': - resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/openbsd-arm64@0.27.7': resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.28.1': - resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-x64@0.27.7': resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.28.1': - resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openharmony-arm64@0.27.7': resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.28.1': - resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/sunos-x64@0.27.7': resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.28.1': - resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/win32-arm64@0.27.7': resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.28.1': - resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-ia32@0.27.7': resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.28.1': - resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-x64@0.27.7': resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.28.1': - resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@ianvs/prettier-plugin-sort-imports@4.7.1': resolution: {integrity: sha512-jmTNYGlg95tlsoG3JLCcuC4BrFELJtLirLAkQW/71lXSyOhVt/Xj7xWbbGcuVbNq1gwWgSyMrPjJc9Z30hynVw==} peerDependencies: @@ -1727,23 +1562,6 @@ packages: cpu: [x64] os: [win32] - '@size-limit/esbuild@12.1.0': - resolution: {integrity: sha512-Um6MVrX+05kIxI4+zk0ZByG9dA/Th1f+sfGc571D95BnCPc90/pl2+2OdsQuOyoWEbeAMqfcTKo0v07i+E65Vw==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - peerDependencies: - size-limit: 12.1.0 - - '@size-limit/file@12.1.0': - resolution: {integrity: sha512-eGwDcIufnNnvJRzv3liDOn6MAOGgmOTUdpeGQ2KuRTlgIgO54AJH1ilvktlJc6PIjNfwpYY0dOGyap1QgM1swQ==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - peerDependencies: - size-limit: 12.1.0 - - '@size-limit/preset-small-lib@12.1.0': - resolution: {integrity: sha512-TVVQ/iuHbaGtHJrjur5s4XKYEyGk0nIwUAqhuzhKPbTyV9nYOH/laDelQ4vg3cGmm8sayRx998wxEdnwM/Yewg==} - peerDependencies: - size-limit: 12.1.0 - '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -2013,10 +1831,6 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} - bytes-iec@3.1.1: - resolution: {integrity: sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==} - engines: {node: '>= 0.8'} - bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -2246,11 +2060,6 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.28.1: - resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} - engines: {node: '>=18'} - hasBin: true - escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -2688,10 +2497,6 @@ packages: resolution: {integrity: sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==} hasBin: true - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -2850,14 +2655,6 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@5.1.16: - resolution: {integrity: sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==} - engines: {node: ^18 || >=20} - hasBin: true - - nanospinner@1.2.2: - resolution: {integrity: sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==} - ncp@2.0.0: resolution: {integrity: sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==} hasBin: true @@ -3259,16 +3056,6 @@ packages: resolution: {integrity: sha512-WszCLXwT4h2k1ufIXAgsbiTOazqqevFCIncOuUBZJ91DdvWcC5+OFkluWRQPrcuSYd8fjq+o2y1QfWqYMoAToQ==} hasBin: true - size-limit@12.1.0: - resolution: {integrity: sha512-VnDS2fycANrJFVPQwjaD+h+hkISY7EB3LsPsYWje4lBCjQwwsZLxjwwRwVJKHrcj2ZqyG+DdXykWm9mbZklZrw==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - hasBin: true - peerDependencies: - jiti: ^2.0.0 - peerDependenciesMeta: - jiti: - optional: true - skip-regex@1.0.2: resolution: {integrity: sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==} engines: {node: '>=4.2'} @@ -4583,12 +4370,12 @@ snapshots: transitivePeerDependencies: - debug - '@codspeed/vitest-plugin@5.4.0(tinybench@2.9.0)(vite@7.3.3(@types/node@25.6.0))(vitest@4.1.6)': + '@codspeed/vitest-plugin@5.4.0(tinybench@2.9.0)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0))(vitest@4.1.6)': dependencies: '@codspeed/core': 5.4.0 tinybench: 2.9.0 - vite: 7.3.3(@types/node@25.6.0) - vitest: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)) + vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) + vitest: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) transitivePeerDependencies: - debug @@ -4636,159 +4423,81 @@ snapshots: '@esbuild/aix-ppc64@0.27.7': optional: true - '@esbuild/aix-ppc64@0.28.1': - optional: true - '@esbuild/android-arm64@0.27.7': optional: true - '@esbuild/android-arm64@0.28.1': - optional: true - '@esbuild/android-arm@0.27.7': optional: true - '@esbuild/android-arm@0.28.1': - optional: true - '@esbuild/android-x64@0.27.7': optional: true - '@esbuild/android-x64@0.28.1': - optional: true - '@esbuild/darwin-arm64@0.27.7': optional: true - '@esbuild/darwin-arm64@0.28.1': - optional: true - '@esbuild/darwin-x64@0.27.7': optional: true - '@esbuild/darwin-x64@0.28.1': - optional: true - '@esbuild/freebsd-arm64@0.27.7': optional: true - '@esbuild/freebsd-arm64@0.28.1': - optional: true - '@esbuild/freebsd-x64@0.27.7': optional: true - '@esbuild/freebsd-x64@0.28.1': - optional: true - '@esbuild/linux-arm64@0.27.7': optional: true - '@esbuild/linux-arm64@0.28.1': - optional: true - '@esbuild/linux-arm@0.27.7': optional: true - '@esbuild/linux-arm@0.28.1': - optional: true - '@esbuild/linux-ia32@0.27.7': optional: true - '@esbuild/linux-ia32@0.28.1': - optional: true - '@esbuild/linux-loong64@0.27.7': optional: true - '@esbuild/linux-loong64@0.28.1': - optional: true - '@esbuild/linux-mips64el@0.27.7': optional: true - '@esbuild/linux-mips64el@0.28.1': - optional: true - '@esbuild/linux-ppc64@0.27.7': optional: true - '@esbuild/linux-ppc64@0.28.1': - optional: true - '@esbuild/linux-riscv64@0.27.7': optional: true - '@esbuild/linux-riscv64@0.28.1': - optional: true - '@esbuild/linux-s390x@0.27.7': optional: true - '@esbuild/linux-s390x@0.28.1': - optional: true - '@esbuild/linux-x64@0.27.7': optional: true - '@esbuild/linux-x64@0.28.1': - optional: true - '@esbuild/netbsd-arm64@0.27.7': optional: true - '@esbuild/netbsd-arm64@0.28.1': - optional: true - '@esbuild/netbsd-x64@0.27.7': optional: true - '@esbuild/netbsd-x64@0.28.1': - optional: true - '@esbuild/openbsd-arm64@0.27.7': optional: true - '@esbuild/openbsd-arm64@0.28.1': - optional: true - '@esbuild/openbsd-x64@0.27.7': optional: true - '@esbuild/openbsd-x64@0.28.1': - optional: true - '@esbuild/openharmony-arm64@0.27.7': optional: true - '@esbuild/openharmony-arm64@0.28.1': - optional: true - '@esbuild/sunos-x64@0.27.7': optional: true - '@esbuild/sunos-x64@0.28.1': - optional: true - '@esbuild/win32-arm64@0.27.7': optional: true - '@esbuild/win32-arm64@0.28.1': - optional: true - '@esbuild/win32-ia32@0.27.7': optional: true - '@esbuild/win32-ia32@0.28.1': - optional: true - '@esbuild/win32-x64@0.27.7': optional: true - '@esbuild/win32-x64@0.28.1': - optional: true - '@ianvs/prettier-plugin-sort-imports@4.7.1(prettier@3.8.1)': dependencies: '@babel/generator': 7.29.1 @@ -5060,22 +4769,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true - '@size-limit/esbuild@12.1.0(size-limit@12.1.0)': - dependencies: - esbuild: 0.28.1 - nanoid: 5.1.16 - size-limit: 12.1.0 - - '@size-limit/file@12.1.0(size-limit@12.1.0)': - dependencies: - size-limit: 12.1.0 - - '@size-limit/preset-small-lib@12.1.0(size-limit@12.1.0)': - dependencies: - '@size-limit/esbuild': 12.1.0(size-limit@12.1.0) - '@size-limit/file': 12.1.0(size-limit@12.1.0) - size-limit: 12.1.0 - '@standard-schema/spec@1.1.0': {} '@types/babel__core@7.20.5': @@ -5184,7 +4877,7 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)) + vitest: 4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) '@vitest/expect@4.1.6': dependencies: @@ -5203,14 +4896,6 @@ snapshots: optionalDependencies: vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) - '@vitest/mocker@4.1.6(vite@7.3.3(@types/node@25.6.0))': - dependencies: - '@vitest/spy': 4.1.6 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 7.3.3(@types/node@25.6.0) - '@vitest/pretty-format@4.1.6': dependencies: tinyrainbow: 3.1.0 @@ -5400,8 +5085,6 @@ snapshots: builtin-modules@3.3.0: {} - bytes-iec@3.1.1: {} - bytes@3.1.2: {} call-bind-apply-helpers@1.0.2: @@ -5617,35 +5300,6 @@ snapshots: '@esbuild/win32-ia32': 0.27.7 '@esbuild/win32-x64': 0.27.7 - esbuild@0.28.1: - optionalDependencies: - '@esbuild/aix-ppc64': 0.28.1 - '@esbuild/android-arm': 0.28.1 - '@esbuild/android-arm64': 0.28.1 - '@esbuild/android-x64': 0.28.1 - '@esbuild/darwin-arm64': 0.28.1 - '@esbuild/darwin-x64': 0.28.1 - '@esbuild/freebsd-arm64': 0.28.1 - '@esbuild/freebsd-x64': 0.28.1 - '@esbuild/linux-arm': 0.28.1 - '@esbuild/linux-arm64': 0.28.1 - '@esbuild/linux-ia32': 0.28.1 - '@esbuild/linux-loong64': 0.28.1 - '@esbuild/linux-mips64el': 0.28.1 - '@esbuild/linux-ppc64': 0.28.1 - '@esbuild/linux-riscv64': 0.28.1 - '@esbuild/linux-s390x': 0.28.1 - '@esbuild/linux-x64': 0.28.1 - '@esbuild/netbsd-arm64': 0.28.1 - '@esbuild/netbsd-x64': 0.28.1 - '@esbuild/openbsd-arm64': 0.28.1 - '@esbuild/openbsd-x64': 0.28.1 - '@esbuild/openharmony-arm64': 0.28.1 - '@esbuild/sunos-x64': 0.28.1 - '@esbuild/win32-arm64': 0.28.1 - '@esbuild/win32-ia32': 0.28.1 - '@esbuild/win32-x64': 0.28.1 - escalade@3.2.0: {} escape-html@1.0.3: {} @@ -6144,8 +5798,6 @@ snapshots: lcov-parse@1.0.0: {} - lilconfig@3.1.3: {} - locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -6275,12 +5927,6 @@ snapshots: nanoid@3.3.11: {} - nanoid@5.1.16: {} - - nanospinner@1.2.2: - dependencies: - picocolors: 1.1.1 - ncp@2.0.0: {} negotiator@0.6.3: {} @@ -6701,14 +6347,6 @@ snapshots: simple-git-hooks@2.13.1: {} - size-limit@12.1.0: - dependencies: - bytes-iec: 3.1.1 - lilconfig: 3.1.3 - nanospinner: 1.2.2 - picocolors: 1.1.1 - tinyglobby: 0.2.16 - skip-regex@1.0.2: {} slash@2.0.0: {} @@ -6940,30 +6578,18 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite-plugin-solid@3.0.0-next.4(vite@7.3.3(@types/node@25.6.0)): + vite-plugin-solid@3.0.0-next.4(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): dependencies: '@babel/core': 7.29.0 '@types/babel__core': 7.20.5 babel-preset-solid: link:packages/babel-preset-solid merge-anything: 5.1.7 solid-refresh: 0.8.0-next.4 - vite: 7.3.3(@types/node@25.6.0) - vitefu: 1.1.2(vite@7.3.3(@types/node@25.6.0)) + vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) + vitefu: 1.1.2(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) transitivePeerDependencies: - supports-color - vite@7.3.3(@types/node@25.6.0): - dependencies: - esbuild: 0.27.7 - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - postcss: 8.5.6 - rollup: 4.59.0 - tinyglobby: 0.2.16 - optionalDependencies: - '@types/node': 25.6.0 - fsevents: 2.3.3 - vite@7.3.3(@types/node@25.6.0)(terser@5.49.0): dependencies: esbuild: 0.27.7 @@ -6977,9 +6603,9 @@ snapshots: fsevents: 2.3.3 terser: 5.49.0 - vitefu@1.1.2(vite@7.3.3(@types/node@25.6.0)): + vitefu@1.1.2(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): optionalDependencies: - vite: 7.3.3(@types/node@25.6.0) + vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) vitest@4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): dependencies: @@ -7010,10 +6636,10 @@ snapshots: transitivePeerDependencies: - msw - vitest@4.1.6(@types/node@25.6.0)(@vitest/coverage-v8@4.1.6)(jsdom@25.0.1)(vite@7.3.3(@types/node@25.6.0)): + vitest@4.1.6(@types/node@25.6.0)(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)): dependencies: '@vitest/expect': 4.1.6 - '@vitest/mocker': 4.1.6(vite@7.3.3(@types/node@25.6.0)) + '@vitest/mocker': 4.1.6(vite@7.3.3(@types/node@25.6.0)(terser@5.49.0)) '@vitest/pretty-format': 4.1.6 '@vitest/runner': 4.1.6 '@vitest/snapshot': 4.1.6 @@ -7030,12 +6656,10 @@ snapshots: tinyexec: 1.1.2 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 - vite: 7.3.3(@types/node@25.6.0) + vite: 7.3.3(@types/node@25.6.0)(terser@5.49.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.6.0 - '@vitest/coverage-v8': 4.1.6(vitest@4.1.6) - jsdom: 25.0.1 transitivePeerDependencies: - msw diff --git a/size/.gitignore b/size/.gitignore new file mode 100644 index 000000000..3c3629e64 --- /dev/null +++ b/size/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/.size-limit.js b/size/.size-limit.js similarity index 52% rename from .size-limit.js rename to size/.size-limit.js index bc44951fc..5fa780563 100644 --- a/.size-limit.js +++ b/size/.size-limit.js @@ -1,46 +1,47 @@ -// Import-cost scenarios for #2883. Bare specifiers resolve via esbuild -// aliases to the built browser-prod artifacts rather than root workspace -// devDeps: adding solid-js/@solidjs/* to the root package.json re-keys -// pnpm's peer graph (vitest/vite-plugin-solid instances), which relocates -// the benchmark harness and shows up as phantom CodSpeed regressions. +// Import-cost scenarios for #2883, measured against the built browser-prod +// artifacts. Bare specifiers resolve via esbuild aliases so nothing here +// touches the workspace dependency graph. Limits carry ~5% headroom over the +// sizes at landing: a breach means tree-shaking regressed (or a deliberate +// feature landed — bump the limit in the same PR and say why). The simple-app +// scenario is pinned at 10 KB on purpose. const alias = { - "solid-js": "./packages/solid/dist/solid.js", - "@solidjs/web": "./packages/solid-web/dist/web.js", - "@solidjs/signals": "./packages/solid-signals/dist/prod/index.js" + "solid-js": "../packages/solid/dist/solid.js", + "@solidjs/web": "../packages/solid-web/dist/web.js", + "@solidjs/signals": "../packages/solid-signals/dist/prod/index.js" }; const modifyEsbuildConfig = config => ({ ...config, alias }); module.exports = [ { name: "signals: core floor (createSignal/Memo/Effect/Root/flush)", - path: "packages/solid-signals/dist/prod/index.js", + path: "../packages/solid-signals/dist/prod/index.js", import: "{ createSignal, createMemo, createEffect, createRoot, flush }", limit: "7.1 KB", modifyEsbuildConfig }, { name: "signals: + createStore", - path: "packages/solid-signals/dist/prod/index.js", + path: "../packages/solid-signals/dist/prod/index.js", import: "{ createSignal, createMemo, createEffect, createRoot, flush, createStore }", limit: "11.6 KB", modifyEsbuildConfig }, { name: "signals: + isPending/latest", - path: "packages/solid-signals/dist/prod/index.js", + path: "../packages/solid-signals/dist/prod/index.js", import: "{ createSignal, createMemo, createEffect, createRoot, flush, isPending, latest }", limit: "8.75 KB", modifyEsbuildConfig }, { name: "app: render + one signal (the simple-app floor)", - path: "size-fixtures/minimal-app.js", + path: "minimal-app.js", limit: "10 KB", modifyEsbuildConfig }, { name: "app: CSR with Show/For/Loading/Errored/lazy", - path: "size-fixtures/csr-app.js", + path: "csr-app.js", limit: "12 KB", modifyEsbuildConfig } diff --git a/size-fixtures/csr-app.js b/size/csr-app.js similarity index 100% rename from size-fixtures/csr-app.js rename to size/csr-app.js diff --git a/size-fixtures/lazy-page.js b/size/lazy-page.js similarity index 100% rename from size-fixtures/lazy-page.js rename to size/lazy-page.js diff --git a/size-fixtures/minimal-app.js b/size/minimal-app.js similarity index 100% rename from size-fixtures/minimal-app.js rename to size/minimal-app.js diff --git a/size/package-lock.json b/size/package-lock.json new file mode 100644 index 000000000..61698e567 --- /dev/null +++ b/size/package-lock.json @@ -0,0 +1,678 @@ +{ + "name": "@solidjs/size-scenarios", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@solidjs/size-scenarios", + "devDependencies": { + "@size-limit/preset-small-lib": "^12.1.0", + "size-limit": "^12.1.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/esbuild/-/esbuild-12.1.0.tgz", + "integrity": "sha512-Um6MVrX+05kIxI4+zk0ZByG9dA/Th1f+sfGc571D95BnCPc90/pl2+2OdsQuOyoWEbeAMqfcTKo0v07i+E65Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.28.0", + "nanoid": "^5.1.7" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "size-limit": "12.1.0" + } + }, + "node_modules/@size-limit/file": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/file/-/file-12.1.0.tgz", + "integrity": "sha512-eGwDcIufnNnvJRzv3liDOn6MAOGgmOTUdpeGQ2KuRTlgIgO54AJH1ilvktlJc6PIjNfwpYY0dOGyap1QgM1swQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "size-limit": "12.1.0" + } + }, + "node_modules/@size-limit/preset-small-lib": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/preset-small-lib/-/preset-small-lib-12.1.0.tgz", + "integrity": "sha512-TVVQ/iuHbaGtHJrjur5s4XKYEyGk0nIwUAqhuzhKPbTyV9nYOH/laDelQ4vg3cGmm8sayRx998wxEdnwM/Yewg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@size-limit/esbuild": "12.1.0", + "@size-limit/file": "12.1.0", + "size-limit": "12.1.0" + }, + "peerDependencies": { + "size-limit": "12.1.0" + } + }, + "node_modules/bytes-iec": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes-iec/-/bytes-iec-3.1.1.tgz", + "integrity": "sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/nanoid": { + "version": "5.1.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.16.tgz", + "integrity": "sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/nanospinner": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/nanospinner/-/nanospinner-1.2.2.tgz", + "integrity": "sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/size-limit": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/size-limit/-/size-limit-12.1.0.tgz", + "integrity": "sha512-VnDS2fycANrJFVPQwjaD+h+hkISY7EB3LsPsYWje4lBCjQwwsZLxjwwRwVJKHrcj2ZqyG+DdXykWm9mbZklZrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes-iec": "^3.1.1", + "lilconfig": "^3.1.3", + "nanospinner": "^1.2.2", + "picocolors": "^1.1.1", + "tinyglobby": "^0.2.16" + }, + "bin": { + "size-limit": "bin.js" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "jiti": "^2.0.0" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + } + } +} diff --git a/size/package.json b/size/package.json new file mode 100644 index 000000000..f7095656e --- /dev/null +++ b/size/package.json @@ -0,0 +1,13 @@ +{ + "name": "@solidjs/size-scenarios", + "private": true, + "description": "Tree-shaken import-cost tracking for #2883. Deliberately OUTSIDE the pnpm workspace with its own npm lockfile: adding these dev tools to the workspace graph re-keys pnpm peer instances (vitest/@codspeed/vitest-plugin), which relocates the benchmark harness and produces phantom CodSpeed regressions.", + "scripts": { + "size": "size-limit", + "build": "cd .. && pnpm install --frozen-lockfile && pnpm build" + }, + "devDependencies": { + "size-limit": "^12.1.0", + "@size-limit/preset-small-lib": "^12.1.0" + } +} From ee84dd12839aeee4418cbfd4b079ebc64e98d78c Mon Sep 17 00:00:00 2001 From: Ryan Carniato Date: Wed, 15 Jul 2026 14:46:38 -0700 Subject: [PATCH 5/5] ci(size): relocate to scripts/size Same isolated-from-the-workspace setup, less top-level clutter; README documents why it must stay outside the pnpm workspace graph. Co-Authored-By: Claude Fable 5 --- .github/workflows/size.yml | 10 +++++----- {size => scripts/size}/.gitignore | 0 {size => scripts/size}/.size-limit.js | 12 ++++++------ scripts/size/README.md | 19 +++++++++++++++++++ {size => scripts/size}/csr-app.js | 0 {size => scripts/size}/lazy-page.js | 0 {size => scripts/size}/minimal-app.js | 0 {size => scripts/size}/package-lock.json | 0 {size => scripts/size}/package.json | 2 +- 9 files changed, 31 insertions(+), 12 deletions(-) rename {size => scripts/size}/.gitignore (100%) rename {size => scripts/size}/.size-limit.js (79%) create mode 100644 scripts/size/README.md rename {size => scripts/size}/csr-app.js (100%) rename {size => scripts/size}/lazy-page.js (100%) rename {size => scripts/size}/minimal-app.js (100%) rename {size => scripts/size}/package-lock.json (100%) rename {size => scripts/size}/package.json (88%) diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml index 2695dbb02..f92340d8a 100644 --- a/.github/workflows/size.yml +++ b/.github/workflows/size.yml @@ -1,6 +1,6 @@ name: Size -# Tracks tree-shaken scenario costs per PR (#2883). The size/ directory is a +# Tracks tree-shaken scenario costs per PR (#2883). scripts/size/ is a # standalone npm package OUTSIDE the pnpm workspace on purpose: adding its # tooling to the workspace graph re-keys pnpm peer instances (vitest, # @codspeed/vitest-plugin), which relocates the benchmark harness and shows @@ -31,12 +31,12 @@ jobs: - run: pnpm install --frozen-lockfile - run: pnpm build - run: npm ci --no-audit --no-fund - working-directory: size + working-directory: scripts/size - run: npm run size - working-directory: size + working-directory: scripts/size # Best-effort base-vs-head delta comment. Requires the base branch to also - # carry size/, so it is informational and never blocks: continue-on-error + # carry scripts/size/, so it is informational and never blocks: continue-on-error # keeps bootstrap PRs (and any action hiccup) green. compare: runs-on: ubuntu-latest @@ -53,5 +53,5 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} package_manager: npm - directory: size + directory: scripts/size build_script: build diff --git a/size/.gitignore b/scripts/size/.gitignore similarity index 100% rename from size/.gitignore rename to scripts/size/.gitignore diff --git a/size/.size-limit.js b/scripts/size/.size-limit.js similarity index 79% rename from size/.size-limit.js rename to scripts/size/.size-limit.js index 5fa780563..54d8118f0 100644 --- a/size/.size-limit.js +++ b/scripts/size/.size-limit.js @@ -5,30 +5,30 @@ // feature landed — bump the limit in the same PR and say why). The simple-app // scenario is pinned at 10 KB on purpose. const alias = { - "solid-js": "../packages/solid/dist/solid.js", - "@solidjs/web": "../packages/solid-web/dist/web.js", - "@solidjs/signals": "../packages/solid-signals/dist/prod/index.js" + "solid-js": "../../packages/solid/dist/solid.js", + "@solidjs/web": "../../packages/solid-web/dist/web.js", + "@solidjs/signals": "../../packages/solid-signals/dist/prod/index.js" }; const modifyEsbuildConfig = config => ({ ...config, alias }); module.exports = [ { name: "signals: core floor (createSignal/Memo/Effect/Root/flush)", - path: "../packages/solid-signals/dist/prod/index.js", + path: "../../packages/solid-signals/dist/prod/index.js", import: "{ createSignal, createMemo, createEffect, createRoot, flush }", limit: "7.1 KB", modifyEsbuildConfig }, { name: "signals: + createStore", - path: "../packages/solid-signals/dist/prod/index.js", + path: "../../packages/solid-signals/dist/prod/index.js", import: "{ createSignal, createMemo, createEffect, createRoot, flush, createStore }", limit: "11.6 KB", modifyEsbuildConfig }, { name: "signals: + isPending/latest", - path: "../packages/solid-signals/dist/prod/index.js", + path: "../../packages/solid-signals/dist/prod/index.js", import: "{ createSignal, createMemo, createEffect, createRoot, flush, isPending, latest }", limit: "8.75 KB", modifyEsbuildConfig diff --git a/scripts/size/README.md b/scripts/size/README.md new file mode 100644 index 000000000..1a451bcb6 --- /dev/null +++ b/scripts/size/README.md @@ -0,0 +1,19 @@ +# Size scenarios (#2883) + +Tree-shaken import-cost tracking: `.size-limit.js` defines scenario entries +(signals floor, +createStore, +isPending/latest, the render+one-signal simple +app, a representative CSR app) with hard gzip-limits. CI fails when a scenario +exceeds its limit — that means tree-shaking regressed, or a deliberate feature +landed and the limit should be bumped in the same PR with a reason. The +simple-app scenario is pinned at 10 KB on purpose. + +This directory is deliberately **outside the pnpm workspace**, with its own +npm lockfile. Its tooling must never enter the workspace dependency graph: +changing that graph re-keys pnpm peer instances (vitest, +@codspeed/vitest-plugin), which relocates the benchmark harness and shows up +as phantom CodSpeed regressions. Nothing here is published (`private: true`). + +Run locally: `cd scripts/size && npm ci && npm run size` (build the repo +first). The retained-module-graph test in +`packages/solid-signals/tests/treeshake.test.ts` is the companion diagnostic +that names the re-coupled module when shaking breaks. diff --git a/size/csr-app.js b/scripts/size/csr-app.js similarity index 100% rename from size/csr-app.js rename to scripts/size/csr-app.js diff --git a/size/lazy-page.js b/scripts/size/lazy-page.js similarity index 100% rename from size/lazy-page.js rename to scripts/size/lazy-page.js diff --git a/size/minimal-app.js b/scripts/size/minimal-app.js similarity index 100% rename from size/minimal-app.js rename to scripts/size/minimal-app.js diff --git a/size/package-lock.json b/scripts/size/package-lock.json similarity index 100% rename from size/package-lock.json rename to scripts/size/package-lock.json diff --git a/size/package.json b/scripts/size/package.json similarity index 88% rename from size/package.json rename to scripts/size/package.json index f7095656e..ce23aff80 100644 --- a/size/package.json +++ b/scripts/size/package.json @@ -4,7 +4,7 @@ "description": "Tree-shaken import-cost tracking for #2883. Deliberately OUTSIDE the pnpm workspace with its own npm lockfile: adding these dev tools to the workspace graph re-keys pnpm peer instances (vitest/@codspeed/vitest-plugin), which relocates the benchmark harness and produces phantom CodSpeed regressions.", "scripts": { "size": "size-limit", - "build": "cd .. && pnpm install --frozen-lockfile && pnpm build" + "build": "cd ../.. && pnpm install --frozen-lockfile && pnpm build" }, "devDependencies": { "size-limit": "^12.1.0",