From 8ea3ee8c62aed631d5c4bbc0870d491059ed7d03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 10:52:21 -0400 Subject: [PATCH 1/4] chore(deps-dev): bump esbuild from 0.25.11 to 0.28.1 (#18427) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [esbuild](https://github.com/evanw/esbuild) from 0.25.11 to 0.28.1.
Release notes

Sourced from esbuild's releases.

v0.28.1

... (truncated)

Changelog

Sourced from esbuild's changelog.

Changelog: 2025

This changelog documents all esbuild versions published in the year 2025 (versions 0.25.0 through 0.27.2).

0.27.2

... (truncated)

Commits
Maintainer changes

This version was pushed to npm by GitHub Actions, a new releaser for esbuild since your current version.


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=esbuild&package-manager=npm_and_yarn&previous-version=0.25.11&new-version=0.28.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/sveltejs/svelte/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packages/svelte/package.json | 2 +- pnpm-lock.yaml | 342 ++++++++++++++++++----------------- 2 files changed, 178 insertions(+), 166 deletions(-) diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 6bca1bd4a8..eeca8e032e 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -161,7 +161,7 @@ "@types/node": "^20.11.5", "baseline-browser-mapping": "^2.10.32", "dts-buddy": "^0.5.5", - "esbuild": "^0.25.10", + "esbuild": "^0.28.1", "rollup": "^4.59.0", "source-map": "^0.7.4", "tinyglobby": "^0.2.12", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a619c24ad6..e86c927efe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -148,8 +148,8 @@ importers: specifier: ^0.5.5 version: 0.5.5(typescript@5.5.4) esbuild: - specifier: ^0.25.10 - version: 0.25.11 + specifier: ^0.28.1 + version: 0.28.1 rollup: specifier: ^4.59.0 version: 4.60.1 @@ -285,23 +285,17 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - '@esbuild/aix-ppc64@0.25.11': - resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.27.7': resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.11': - resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} engines: {node: '>=18'} - cpu: [arm64] - os: [android] + cpu: [ppc64] + os: [aix] '@esbuild/android-arm64@0.27.7': resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} @@ -309,10 +303,10 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.11': - resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} engines: {node: '>=18'} - cpu: [arm] + cpu: [arm64] os: [android] '@esbuild/android-arm@0.27.7': @@ -321,10 +315,10 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.11': - resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} engines: {node: '>=18'} - cpu: [x64] + cpu: [arm] os: [android] '@esbuild/android-x64@0.27.7': @@ -333,11 +327,11 @@ packages: cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.11': - resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] + cpu: [x64] + os: [android] '@esbuild/darwin-arm64@0.27.7': resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} @@ -345,10 +339,10 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.11': - resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} engines: {node: '>=18'} - cpu: [x64] + cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.27.7': @@ -357,11 +351,11 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.11': - resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] + cpu: [x64] + os: [darwin] '@esbuild/freebsd-arm64@0.27.7': resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} @@ -369,10 +363,10 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.11': - resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} engines: {node: '>=18'} - cpu: [x64] + cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.27.7': @@ -381,11 +375,11 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.11': - resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} engines: {node: '>=18'} - cpu: [arm64] - os: [linux] + cpu: [x64] + os: [freebsd] '@esbuild/linux-arm64@0.27.7': resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} @@ -393,10 +387,10 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.11': - resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} engines: {node: '>=18'} - cpu: [arm] + cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.27.7': @@ -405,10 +399,10 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.11': - resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} engines: {node: '>=18'} - cpu: [ia32] + cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.27.7': @@ -417,10 +411,10 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.11': - resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} engines: {node: '>=18'} - cpu: [loong64] + cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.27.7': @@ -429,10 +423,10 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.11': - resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} engines: {node: '>=18'} - cpu: [mips64el] + cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.27.7': @@ -441,10 +435,10 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.11': - resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} engines: {node: '>=18'} - cpu: [ppc64] + cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.27.7': @@ -453,10 +447,10 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.11': - resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} engines: {node: '>=18'} - cpu: [riscv64] + cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.27.7': @@ -465,10 +459,10 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.11': - resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} engines: {node: '>=18'} - cpu: [s390x] + cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.27.7': @@ -477,10 +471,10 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.11': - resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} engines: {node: '>=18'} - cpu: [x64] + cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.27.7': @@ -489,11 +483,11 @@ packages: cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.11': - resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] + cpu: [x64] + os: [linux] '@esbuild/netbsd-arm64@0.27.7': resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} @@ -501,10 +495,10 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.11': - resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} engines: {node: '>=18'} - cpu: [x64] + cpu: [arm64] os: [netbsd] '@esbuild/netbsd-x64@0.27.7': @@ -513,11 +507,11 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.11': - resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] + cpu: [x64] + os: [netbsd] '@esbuild/openbsd-arm64@0.27.7': resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} @@ -525,10 +519,10 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.11': - resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} engines: {node: '>=18'} - cpu: [x64] + cpu: [arm64] os: [openbsd] '@esbuild/openbsd-x64@0.27.7': @@ -537,11 +531,11 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.11': - resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] + cpu: [x64] + os: [openbsd] '@esbuild/openharmony-arm64@0.27.7': resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} @@ -549,11 +543,11 @@ packages: cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.11': - resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} engines: {node: '>=18'} - cpu: [x64] - os: [sunos] + cpu: [arm64] + os: [openharmony] '@esbuild/sunos-x64@0.27.7': resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} @@ -561,11 +555,11 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.11': - resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} engines: {node: '>=18'} - cpu: [arm64] - os: [win32] + cpu: [x64] + os: [sunos] '@esbuild/win32-arm64@0.27.7': resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} @@ -573,10 +567,10 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.11': - resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} engines: {node: '>=18'} - cpu: [ia32] + cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.27.7': @@ -585,10 +579,10 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.11': - resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} engines: {node: '>=18'} - cpu: [x64] + cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.27.7': @@ -597,6 +591,12 @@ packages: 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] + '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -936,6 +936,7 @@ packages: '@svitejs/changesets-changelog-github-compact@1.1.0': resolution: {integrity: sha512-qhUGGDHcpbY2zpjW3SwqchuW8J/5EzlPFud7xNntHKA7f3a/mx5+g+ruJKFHSAiVZYo30PALt+AyhmPUNKH/Og==} engines: {node: ^14.13.1 || ^16.0.0 || >=18} + deprecated: unmaintained '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1090,6 +1091,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@7.1.1: resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} engines: {node: '>= 14'} @@ -1287,8 +1293,8 @@ packages: peerDependencies: typescript: '>=5.0.4 <5.8' - enhanced-resolve@5.22.1: - resolution: {integrity: sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==} + enhanced-resolve@5.24.0: + resolution: {integrity: sha512-SkE2t82KlkkxQRVMVLAGKxLfORGQfrkx5dkj+vlgXRVNEdPc4eZcR+J/Fvj8C+yKSFH5L0q3NFlyufOVQnCcYQ==} engines: {node: '>=10.13.0'} enquirer@2.4.1: @@ -1305,13 +1311,13 @@ packages: es-module-lexer@2.1.0: resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} - esbuild@0.25.11: - resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} hasBin: true - esbuild@0.27.7: - resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} engines: {node: '>=18'} hasBin: true @@ -2095,8 +2101,8 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.8.1: - resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} engines: {node: '>=10'} hasBin: true @@ -2663,162 +2669,162 @@ snapshots: human-id: 4.1.1 prettier: 2.8.8 - '@esbuild/aix-ppc64@0.25.11': - optional: true - '@esbuild/aix-ppc64@0.27.7': optional: true - '@esbuild/android-arm64@0.25.11': + '@esbuild/aix-ppc64@0.28.1': optional: true '@esbuild/android-arm64@0.27.7': optional: true - '@esbuild/android-arm@0.25.11': + '@esbuild/android-arm64@0.28.1': optional: true '@esbuild/android-arm@0.27.7': optional: true - '@esbuild/android-x64@0.25.11': + '@esbuild/android-arm@0.28.1': optional: true '@esbuild/android-x64@0.27.7': optional: true - '@esbuild/darwin-arm64@0.25.11': + '@esbuild/android-x64@0.28.1': optional: true '@esbuild/darwin-arm64@0.27.7': optional: true - '@esbuild/darwin-x64@0.25.11': + '@esbuild/darwin-arm64@0.28.1': optional: true '@esbuild/darwin-x64@0.27.7': optional: true - '@esbuild/freebsd-arm64@0.25.11': + '@esbuild/darwin-x64@0.28.1': optional: true '@esbuild/freebsd-arm64@0.27.7': optional: true - '@esbuild/freebsd-x64@0.25.11': + '@esbuild/freebsd-arm64@0.28.1': optional: true '@esbuild/freebsd-x64@0.27.7': optional: true - '@esbuild/linux-arm64@0.25.11': + '@esbuild/freebsd-x64@0.28.1': optional: true '@esbuild/linux-arm64@0.27.7': optional: true - '@esbuild/linux-arm@0.25.11': + '@esbuild/linux-arm64@0.28.1': optional: true '@esbuild/linux-arm@0.27.7': optional: true - '@esbuild/linux-ia32@0.25.11': + '@esbuild/linux-arm@0.28.1': optional: true '@esbuild/linux-ia32@0.27.7': optional: true - '@esbuild/linux-loong64@0.25.11': + '@esbuild/linux-ia32@0.28.1': optional: true '@esbuild/linux-loong64@0.27.7': optional: true - '@esbuild/linux-mips64el@0.25.11': + '@esbuild/linux-loong64@0.28.1': optional: true '@esbuild/linux-mips64el@0.27.7': optional: true - '@esbuild/linux-ppc64@0.25.11': + '@esbuild/linux-mips64el@0.28.1': optional: true '@esbuild/linux-ppc64@0.27.7': optional: true - '@esbuild/linux-riscv64@0.25.11': + '@esbuild/linux-ppc64@0.28.1': optional: true '@esbuild/linux-riscv64@0.27.7': optional: true - '@esbuild/linux-s390x@0.25.11': + '@esbuild/linux-riscv64@0.28.1': optional: true '@esbuild/linux-s390x@0.27.7': optional: true - '@esbuild/linux-x64@0.25.11': + '@esbuild/linux-s390x@0.28.1': optional: true '@esbuild/linux-x64@0.27.7': optional: true - '@esbuild/netbsd-arm64@0.25.11': + '@esbuild/linux-x64@0.28.1': optional: true '@esbuild/netbsd-arm64@0.27.7': optional: true - '@esbuild/netbsd-x64@0.25.11': + '@esbuild/netbsd-arm64@0.28.1': optional: true '@esbuild/netbsd-x64@0.27.7': optional: true - '@esbuild/openbsd-arm64@0.25.11': + '@esbuild/netbsd-x64@0.28.1': optional: true '@esbuild/openbsd-arm64@0.27.7': optional: true - '@esbuild/openbsd-x64@0.25.11': + '@esbuild/openbsd-arm64@0.28.1': optional: true '@esbuild/openbsd-x64@0.27.7': optional: true - '@esbuild/openharmony-arm64@0.25.11': + '@esbuild/openbsd-x64@0.28.1': optional: true '@esbuild/openharmony-arm64@0.27.7': optional: true - '@esbuild/sunos-x64@0.25.11': + '@esbuild/openharmony-arm64@0.28.1': optional: true '@esbuild/sunos-x64@0.27.7': optional: true - '@esbuild/win32-arm64@0.25.11': + '@esbuild/sunos-x64@0.28.1': optional: true '@esbuild/win32-arm64@0.27.7': optional: true - '@esbuild/win32-ia32@0.25.11': + '@esbuild/win32-arm64@0.28.1': optional: true '@esbuild/win32-ia32@0.27.7': optional: true - '@esbuild/win32-x64@0.25.11': + '@esbuild/win32-ia32@0.28.1': optional: true '@esbuild/win32-x64@0.27.7': optional: true + '@esbuild/win32-x64@0.28.1': + optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@10.0.0)': dependencies: eslint: 10.0.0 @@ -3062,7 +3068,7 @@ snapshots: '@stylistic/eslint-plugin-js@1.8.0(eslint@10.0.0)': dependencies: '@types/eslint': 8.56.12 - acorn: 8.16.0 + acorn: 8.17.0 escape-string-regexp: 4.0.0 eslint: 10.0.0 eslint-visitor-keys: 3.4.3 @@ -3303,8 +3309,14 @@ snapshots: dependencies: acorn: 8.16.0 + acorn-jsx@5.3.2(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + acorn@8.16.0: {} + acorn@8.17.0: {} + agent-base@7.1.1: dependencies: debug: 4.4.3 @@ -3475,7 +3487,7 @@ snapshots: ts-api-utils: 1.3.0(typescript@5.5.4) typescript: 5.5.4 - enhanced-resolve@5.22.1: + enhanced-resolve@5.24.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -3491,35 +3503,6 @@ snapshots: es-module-lexer@2.1.0: {} - esbuild@0.25.11: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.11 - '@esbuild/android-arm': 0.25.11 - '@esbuild/android-arm64': 0.25.11 - '@esbuild/android-x64': 0.25.11 - '@esbuild/darwin-arm64': 0.25.11 - '@esbuild/darwin-x64': 0.25.11 - '@esbuild/freebsd-arm64': 0.25.11 - '@esbuild/freebsd-x64': 0.25.11 - '@esbuild/linux-arm': 0.25.11 - '@esbuild/linux-arm64': 0.25.11 - '@esbuild/linux-ia32': 0.25.11 - '@esbuild/linux-loong64': 0.25.11 - '@esbuild/linux-mips64el': 0.25.11 - '@esbuild/linux-ppc64': 0.25.11 - '@esbuild/linux-riscv64': 0.25.11 - '@esbuild/linux-s390x': 0.25.11 - '@esbuild/linux-x64': 0.25.11 - '@esbuild/netbsd-arm64': 0.25.11 - '@esbuild/netbsd-x64': 0.25.11 - '@esbuild/openbsd-arm64': 0.25.11 - '@esbuild/openbsd-x64': 0.25.11 - '@esbuild/openharmony-arm64': 0.25.11 - '@esbuild/sunos-x64': 0.25.11 - '@esbuild/win32-arm64': 0.25.11 - '@esbuild/win32-ia32': 0.25.11 - '@esbuild/win32-x64': 0.25.11 - esbuild@0.27.7: optionalDependencies: '@esbuild/aix-ppc64': 0.27.7 @@ -3549,12 +3532,41 @@ 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 + escape-string-regexp@4.0.0: {} eslint-compat-utils@0.5.1(eslint@10.0.0): dependencies: eslint: 10.0.0 - semver: 7.8.1 + semver: 7.8.4 eslint-config-prettier@9.1.0(eslint@10.0.0): dependencies: @@ -3574,14 +3586,14 @@ snapshots: eslint-plugin-n@17.24.0(eslint@10.0.0)(typescript@5.5.4): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.0) - enhanced-resolve: 5.22.1 + enhanced-resolve: 5.24.0 eslint: 10.0.0 eslint-plugin-es-x: 7.8.0(eslint@10.0.0) get-tsconfig: 4.14.0 globals: 15.15.0 globrex: 0.1.2 ignore: 5.3.2 - semver: 7.8.1 + semver: 7.8.4 ts-declaration-location: 1.0.7(typescript@5.5.4) transitivePeerDependencies: - typescript @@ -3673,8 +3685,8 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} @@ -4312,7 +4324,7 @@ snapshots: semver@7.7.4: {} - semver@7.8.1: {} + semver@7.8.4: {} serialize-javascript@6.0.2: dependencies: From 0510174bc0c908c9d4980274717191fdf46a38c6 Mon Sep 17 00:00:00 2001 From: Nic Polumeyv Date: Mon, 15 Jun 2026 12:08:45 -0400 Subject: [PATCH 2/4] fix: make `SvelteURLSearchParams` notifications accurate (#18425) `SvelteURLSearchParams` has two notification bugs that surface through `SvelteURL`. The first is over-notification. Setting `url.href` always rebuilds the params and bumps their version signal, even when the search string didn't change at all. Effects that read `size` (or any params method) re-run on every unrelated `href` write, which is #17218, where it caused infinite effect loops in a router. The fix is a guard in the internal replace path that bails out when the incoming params serialize identically to the current ones. The second is under-notification, and it's sneakier. Every read method tracks the version signal, `get`, `getAll`, `has`, `keys`, `values`, `entries`, `toString`, `size`, the iterator... except `forEach`, which was never overridden. The inherited platform method reads the internal list directly and subscribes to nothing, so a template that renders params via `forEach` never updates: ```js $effect(() => { url.searchParams.forEach((value, key) => entries.push(`${key}=${value}`)); // never re-runs }); ``` We found this one in the wild while making `page.url` a `SvelteURL` in sveltejs/kit#16031. Kit's own test suite renders query params with `forEach`, and the coarse object-identity signal that previously masked the gap went away, leaving stale UI after client-side navigations. The fix is the same one-line tracking pattern every other read method already uses. Fixes #17218 --- - [x] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs - [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`. - [x] This message body should clearly illustrate what problems it solves. - [x] Ideally, include a test that fails without this PR but passes with it. - [x] If this PR changes code within `packages/svelte/src`, add a changeset (`npx changeset`). ### Tests and linting - [x] Run the tests with `pnpm test` and lint the project with `pnpm lint` --- .changeset/quick-meals-shout.md | 5 ++ .../src/reactivity/url-search-params.js | 15 ++++ .../src/reactivity/url-search-params.test.ts | 21 ++++++ packages/svelte/src/reactivity/url.test.ts | 74 +++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 .changeset/quick-meals-shout.md diff --git a/.changeset/quick-meals-shout.md b/.changeset/quick-meals-shout.md new file mode 100644 index 0000000000..21871edd67 --- /dev/null +++ b/.changeset/quick-meals-shout.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't notify `searchParams` subscribers when the URL changes without affecting the search string diff --git a/packages/svelte/src/reactivity/url-search-params.js b/packages/svelte/src/reactivity/url-search-params.js index 38cf3ebe4f..d745bb6b08 100644 --- a/packages/svelte/src/reactivity/url-search-params.js +++ b/packages/svelte/src/reactivity/url-search-params.js @@ -54,6 +54,11 @@ export class SvelteURLSearchParams extends URLSearchParams { */ [REPLACE](params) { if (this.#updating) return; + + // the URL may have changed in a way that leaves the search string untouched — + // don't rebuild the params or notify readers if nothing changed + if (params.toString() === super.toString()) return; + this.#updating = true; for (const key of [...super.keys()]) { @@ -126,6 +131,16 @@ export class SvelteURLSearchParams extends URLSearchParams { return super.keys(); } + /** + * @param {(value: string, key: string, parent: URLSearchParams) => void} callback + * @param {any} [this_arg] + * @returns {void} + */ + forEach(callback, this_arg) { + get(this.#version); + super.forEach(callback, this_arg); + } + /** * @param {string} name * @param {string} value diff --git a/packages/svelte/src/reactivity/url-search-params.test.ts b/packages/svelte/src/reactivity/url-search-params.test.ts index b0c84872b0..765b4020f3 100644 --- a/packages/svelte/src/reactivity/url-search-params.test.ts +++ b/packages/svelte/src/reactivity/url-search-params.test.ts @@ -244,3 +244,24 @@ test('URLSearchParams.toString', () => { test('SvelteURLSearchParams instanceof URLSearchParams', () => { assert.ok(new SvelteURLSearchParams() instanceof URLSearchParams); }); + +test('params.forEach is reactive', () => { + const params = new SvelteURLSearchParams('foo=1'); + const log: any = []; + + const cleanup = effect_root(() => { + render_effect(() => { + const entries: string[] = []; + params.forEach((value, key) => entries.push(`${key}=${value}`)); + log.push(entries.join('&')); + }); + }); + + flushSync(() => { + params.set('foo', '2'); + }); + + assert.deepEqual(log, ['foo=1', 'foo=2']); + + cleanup(); +}); diff --git a/packages/svelte/src/reactivity/url.test.ts b/packages/svelte/src/reactivity/url.test.ts index a79aa32315..d698116421 100644 --- a/packages/svelte/src/reactivity/url.test.ts +++ b/packages/svelte/src/reactivity/url.test.ts @@ -166,3 +166,77 @@ test('url.search normalizes value', () => { test('SvelteURL instanceof URL', () => { assert.ok(new SvelteURL('https://svelte.dev') instanceof URL); }); + +test('url.searchParams subscribers are not notified by changes that leave the search string untouched', () => { + const url = new SvelteURL('https://svelte.dev/a?foo=bar'); + const log: any = []; + + const cleanup = effect_root(() => { + render_effect(() => { + log.push(url.searchParams.toString()); + }); + }); + + flushSync(() => { + // does not affect the search string + url.pathname = '/b'; + }); + + flushSync(() => { + // neither does this + url.href = 'https://svelte.dev/c?foo=bar#hash'; + }); + + flushSync(() => { + // but this does + url.search = '?foo=baz'; + }); + + assert.deepEqual(log, ['foo=bar', 'foo=baz']); + + cleanup(); +}); + +test('url.searchParams.size is not notified by unrelated href changes', () => { + const url = new SvelteURL('https://svelte.dev/?foo=bar'); + const log: any = []; + + const cleanup = effect_root(() => { + render_effect(() => { + log.push(url.searchParams.size); + }); + }); + + flushSync(() => { + url.href = 'https://svelte.dev/other?foo=bar'; + }); + + flushSync(() => { + url.searchParams.append('baz', 'qux'); + }); + + assert.deepEqual(log, [1, 2]); + + cleanup(); +}); + +test('url.searchParams.forEach re-runs when the search string changes via the URL', () => { + const url = new SvelteURL('https://svelte.dev/?foo=1'); + const log: any = []; + + const cleanup = effect_root(() => { + render_effect(() => { + const entries: string[] = []; + url.searchParams.forEach((value, key) => entries.push(`${key}=${value}`)); + log.push(entries.join('&')); + }); + }); + + flushSync(() => { + url.href = 'https://svelte.dev/?bar=2'; + }); + + assert.deepEqual(log, ['foo=1', 'bar=2']); + + cleanup(); +}); From c4daa490bbbf483ebba117c1afb6f71b4b19e63c Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Tue, 16 Jun 2026 01:18:02 +0900 Subject: [PATCH 3/4] fix: include wrapping parentheses in `{@const}` declarator end (#18436) `{@const x = (a)}` (and any `{@const}` whose initializer is wrapped in parentheses, e.g. `(a = b)`, `({ ... })`) produced a `VariableDeclarator` whose `end` fell before the closing `)`. `read_expression` strips the wrapping parens from the returned node but advances the parser past them, so `init.end` excludes the `)` while the parser position does not. Use the parser position for the declarator `end` instead. Fixes source slices / tooling that rely on the node range (the range previously yielded invalid, unbalanced source). image ### Before submitting the PR, please make sure you do the following - [x] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs - [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`. - [x] This message body should clearly illustrate what problems it solves. - [x] Ideally, include a test that fails without this PR but passes with it. - [x] If this PR changes code within `packages/svelte/src`, add a changeset (`npx changeset`). ### Tests and linting - [ ] Run the tests with `pnpm test` and lint the project with `pnpm lint` --- .changeset/clean-melons-attack.md | 5 + .../src/compiler/phases/1-parse/state/tag.js | 6 +- .../const-tag-parenthesized-init/input.svelte | 6 + .../const-tag-parenthesized-init/output.json | 527 ++++++++++++++++++ 4 files changed, 543 insertions(+), 1 deletion(-) create mode 100644 .changeset/clean-melons-attack.md create mode 100644 packages/svelte/tests/parser-modern/samples/const-tag-parenthesized-init/input.svelte create mode 100644 packages/svelte/tests/parser-modern/samples/const-tag-parenthesized-init/output.json diff --git a/.changeset/clean-melons-attack.md b/.changeset/clean-melons-attack.md new file mode 100644 index 0000000000..8b5a9f2066 --- /dev/null +++ b/.changeset/clean-melons-attack.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: include wrapping parentheses in `{@const}` declarator `end` position diff --git a/packages/svelte/src/compiler/phases/1-parse/state/tag.js b/packages/svelte/src/compiler/phases/1-parse/state/tag.js index 15c79e0353..f5314d04ed 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/tag.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/tag.js @@ -783,6 +783,8 @@ function special(parser) { const expression_start = parser.index; const init = read_expression(parser); + // parser is past wrapping parens, but `init.end` is not — use the parser position + const declarator_end = parser.index; if ( init.type === 'SequenceExpression' && !parser.template.substring(expression_start, init.start).includes('(') @@ -801,7 +803,9 @@ function special(parser) { declaration: { type: 'VariableDeclaration', kind: 'const', - declarations: [{ type: 'VariableDeclarator', id, init, start: id.start, end: init.end }], + declarations: [ + { type: 'VariableDeclarator', id, init, start: id.start, end: declarator_end } + ], start: start + 2, // start at const, not at @const end: parser.index - 1 }, diff --git a/packages/svelte/tests/parser-modern/samples/const-tag-parenthesized-init/input.svelte b/packages/svelte/tests/parser-modern/samples/const-tag-parenthesized-init/input.svelte new file mode 100644 index 0000000000..39bf04093e --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/const-tag-parenthesized-init/input.svelte @@ -0,0 +1,6 @@ +{#each items as item} + {@const x = (item.value)} + {@const y = (a = item.n)} + {@const z = ({ a: item.a })} + {x}{y}{z.a} +{/each} diff --git a/packages/svelte/tests/parser-modern/samples/const-tag-parenthesized-init/output.json b/packages/svelte/tests/parser-modern/samples/const-tag-parenthesized-init/output.json new file mode 100644 index 0000000000..3e8d8b23d5 --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/const-tag-parenthesized-init/output.json @@ -0,0 +1,527 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 126, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "EachBlock", + "start": 0, + "end": 126, + "expression": { + "type": "Identifier", + "start": 7, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "name": "items" + }, + "body": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 21, + "end": 23, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "ConstTag", + "start": 23, + "end": 48, + "declaration": { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "start": 31, + "end": 32, + "loc": { + "start": { + "line": 2, + "column": 9, + "character": 31 + }, + "end": { + "line": 2, + "column": 10, + "character": 32 + } + } + }, + "init": { + "type": "MemberExpression", + "start": 36, + "end": 46, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 24 + } + }, + "object": { + "type": "Identifier", + "start": 36, + "end": 40, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 18 + } + }, + "name": "item" + }, + "property": { + "type": "Identifier", + "start": 41, + "end": 46, + "loc": { + "start": { + "line": 2, + "column": 19 + }, + "end": { + "line": 2, + "column": 24 + } + }, + "name": "value" + }, + "computed": false, + "optional": false + }, + "start": 31, + "end": 47 + } + ], + "start": 25, + "end": 47 + } + }, + { + "type": "Text", + "start": 48, + "end": 50, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "ConstTag", + "start": 50, + "end": 75, + "declaration": { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "start": 58, + "end": 59, + "loc": { + "start": { + "line": 3, + "column": 9, + "character": 58 + }, + "end": { + "line": 3, + "column": 10, + "character": 59 + } + } + }, + "init": { + "type": "AssignmentExpression", + "start": 63, + "end": 73, + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 3, + "column": 24 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 63, + "end": 64, + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 3, + "column": 15 + } + }, + "name": "a" + }, + "right": { + "type": "MemberExpression", + "start": 67, + "end": 73, + "loc": { + "start": { + "line": 3, + "column": 18 + }, + "end": { + "line": 3, + "column": 24 + } + }, + "object": { + "type": "Identifier", + "start": 67, + "end": 71, + "loc": { + "start": { + "line": 3, + "column": 18 + }, + "end": { + "line": 3, + "column": 22 + } + }, + "name": "item" + }, + "property": { + "type": "Identifier", + "start": 72, + "end": 73, + "loc": { + "start": { + "line": 3, + "column": 23 + }, + "end": { + "line": 3, + "column": 24 + } + }, + "name": "n" + }, + "computed": false, + "optional": false + } + }, + "start": 58, + "end": 74 + } + ], + "start": 52, + "end": 74 + } + }, + { + "type": "Text", + "start": 75, + "end": 77, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "ConstTag", + "start": 77, + "end": 105, + "declaration": { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "z", + "start": 85, + "end": 86, + "loc": { + "start": { + "line": 4, + "column": 9, + "character": 85 + }, + "end": { + "line": 4, + "column": 10, + "character": 86 + } + } + }, + "init": { + "type": "ObjectExpression", + "start": 90, + "end": 103, + "loc": { + "start": { + "line": 4, + "column": 14 + }, + "end": { + "line": 4, + "column": 27 + } + }, + "properties": [ + { + "type": "Property", + "start": 92, + "end": 101, + "loc": { + "start": { + "line": 4, + "column": 16 + }, + "end": { + "line": 4, + "column": 25 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 92, + "end": 93, + "loc": { + "start": { + "line": 4, + "column": 16 + }, + "end": { + "line": 4, + "column": 17 + } + }, + "name": "a" + }, + "value": { + "type": "MemberExpression", + "start": 95, + "end": 101, + "loc": { + "start": { + "line": 4, + "column": 19 + }, + "end": { + "line": 4, + "column": 25 + } + }, + "object": { + "type": "Identifier", + "start": 95, + "end": 99, + "loc": { + "start": { + "line": 4, + "column": 19 + }, + "end": { + "line": 4, + "column": 23 + } + }, + "name": "item" + }, + "property": { + "type": "Identifier", + "start": 100, + "end": 101, + "loc": { + "start": { + "line": 4, + "column": 24 + }, + "end": { + "line": 4, + "column": 25 + } + }, + "name": "a" + }, + "computed": false, + "optional": false + }, + "kind": "init" + } + ] + }, + "start": 85, + "end": 104 + } + ], + "start": 79, + "end": 104 + } + }, + { + "type": "Text", + "start": 105, + "end": 107, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "ExpressionTag", + "start": 107, + "end": 110, + "expression": { + "type": "Identifier", + "start": 108, + "end": 109, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 5, + "column": 3 + } + }, + "name": "x" + } + }, + { + "type": "ExpressionTag", + "start": 110, + "end": 113, + "expression": { + "type": "Identifier", + "start": 111, + "end": 112, + "loc": { + "start": { + "line": 5, + "column": 5 + }, + "end": { + "line": 5, + "column": 6 + } + }, + "name": "y" + } + }, + { + "type": "ExpressionTag", + "start": 113, + "end": 118, + "expression": { + "type": "MemberExpression", + "start": 114, + "end": 117, + "loc": { + "start": { + "line": 5, + "column": 8 + }, + "end": { + "line": 5, + "column": 11 + } + }, + "object": { + "type": "Identifier", + "start": 114, + "end": 115, + "loc": { + "start": { + "line": 5, + "column": 8 + }, + "end": { + "line": 5, + "column": 9 + } + }, + "name": "z" + }, + "property": { + "type": "Identifier", + "start": 116, + "end": 117, + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 11 + } + }, + "name": "a" + }, + "computed": false, + "optional": false + } + }, + { + "type": "Text", + "start": 118, + "end": 119, + "raw": "\n", + "data": "\n" + } + ] + }, + "context": { + "type": "Identifier", + "name": "item", + "start": 16, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 16, + "character": 16 + }, + "end": { + "line": 1, + "column": 20, + "character": 20 + } + } + } + } + ] + }, + "options": null +} From d39049edc5567c2c74d9465d5c0f4a3786a83901 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Tue, 16 Jun 2026 12:45:51 +0200 Subject: [PATCH 4/4] fix: lint --- packages/svelte/tests/types/component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/svelte/tests/types/component.ts b/packages/svelte/tests/types/component.ts index 588374229c..533e8f1cbe 100644 --- a/packages/svelte/tests/types/component.ts +++ b/packages/svelte/tests/types/component.ts @@ -334,7 +334,6 @@ mount(functionComponent, { } }); - hydrate(functionComponent, { target: null as any as Document | Element | ShadowRoot, props: {