diff --git a/.changeset/angry-weeks-design.md b/.changeset/angry-weeks-design.md new file mode 100644 index 0000000000..897f2e2192 --- /dev/null +++ b/.changeset/angry-weeks-design.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure reactive graph is fully traversed in the marking phase for non-runes mode diff --git a/.changeset/beige-lamps-ring.md b/.changeset/beige-lamps-ring.md new file mode 100644 index 0000000000..f647921060 --- /dev/null +++ b/.changeset/beige-lamps-ring.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: always return true from `deleteProperty` trap diff --git a/.changeset/clean-shirts-yawn.md b/.changeset/clean-shirts-yawn.md new file mode 100644 index 0000000000..12b113baa1 --- /dev/null +++ b/.changeset/clean-shirts-yawn.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +breaking: throw error if derived creates state and then depends on it diff --git a/.changeset/eighty-mails-develop.md b/.changeset/eighty-mails-develop.md new file mode 100644 index 0000000000..94eee085f7 --- /dev/null +++ b/.changeset/eighty-mails-develop.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: render undefined html as the empty string diff --git a/.changeset/eleven-icons-sniff.md b/.changeset/eleven-icons-sniff.md new file mode 100644 index 0000000000..fd2b1af9c5 --- /dev/null +++ b/.changeset/eleven-icons-sniff.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: error on incorrect attributes for svelte:body diff --git a/.changeset/few-walls-check.md b/.changeset/few-walls-check.md new file mode 100644 index 0000000000..b91ab9d844 --- /dev/null +++ b/.changeset/few-walls-check.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: prevent div/0 when generating transition keyframes diff --git a/.changeset/five-maps-reflect.md b/.changeset/five-maps-reflect.md new file mode 100644 index 0000000000..bdc8d6ec18 --- /dev/null +++ b/.changeset/five-maps-reflect.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure assignments to state field inside constructor trigger effects diff --git a/.changeset/five-shirts-run.md b/.changeset/five-shirts-run.md new file mode 100644 index 0000000000..0a4f285c7d --- /dev/null +++ b/.changeset/five-shirts-run.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: use WAAPI to control timing of JS-based animations diff --git a/.changeset/gentle-needles-train.md b/.changeset/gentle-needles-train.md new file mode 100644 index 0000000000..578d495062 --- /dev/null +++ b/.changeset/gentle-needles-train.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: error on invalid element name diff --git a/.changeset/green-baboons-sip.md b/.changeset/green-baboons-sip.md new file mode 100644 index 0000000000..91d7902867 --- /dev/null +++ b/.changeset/green-baboons-sip.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure $inspect works with SvelteMap and SvelteSet diff --git a/.changeset/green-windows-tap.md b/.changeset/green-windows-tap.md new file mode 100644 index 0000000000..964d6373bc --- /dev/null +++ b/.changeset/green-windows-tap.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: handle deletions of previously-unread state proxy properties diff --git a/.changeset/happy-dolls-joke.md b/.changeset/happy-dolls-joke.md new file mode 100644 index 0000000000..8966d5ad2f --- /dev/null +++ b/.changeset/happy-dolls-joke.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: better compile errors for invalid tag names/placement diff --git a/.changeset/khaki-donkeys-jump.md b/.changeset/khaki-donkeys-jump.md new file mode 100644 index 0000000000..ccac0ff12f --- /dev/null +++ b/.changeset/khaki-donkeys-jump.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: properly handle proxied array length mutations diff --git a/.changeset/light-tigers-smoke.md b/.changeset/light-tigers-smoke.md new file mode 100644 index 0000000000..c26824a41c --- /dev/null +++ b/.changeset/light-tigers-smoke.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: allow deleting non-existent `$$restProps` properties diff --git a/.changeset/mighty-poets-fix.md b/.changeset/mighty-poets-fix.md new file mode 100644 index 0000000000..e41517360e --- /dev/null +++ b/.changeset/mighty-poets-fix.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +chore: default options.filename to "(unknown)" diff --git a/.changeset/olive-llamas-warn.md b/.changeset/olive-llamas-warn.md new file mode 100644 index 0000000000..4cfbf1a763 --- /dev/null +++ b/.changeset/olive-llamas-warn.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: properly transform destructured `$derived.by` declarations diff --git a/.changeset/orange-sheep-exist.md b/.changeset/orange-sheep-exist.md new file mode 100644 index 0000000000..fe10bb0132 --- /dev/null +++ b/.changeset/orange-sheep-exist.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: insert comment before text in an each block, to prevent glued nodes diff --git a/.changeset/pre.json b/.changeset/pre.json index 7cf3bd4574..2941c37e3e 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -21,6 +21,7 @@ "beige-cobras-smoke", "beige-flies-wash", "beige-gifts-appear", + "beige-lamps-ring", "beige-mirrors-listen", "beige-rabbits-shave", "beige-seas-share", @@ -82,6 +83,7 @@ "clean-cats-wave", "clean-eels-beg", "clean-melons-wash", + "clean-shirts-yawn", "clever-chefs-relate", "clever-maps-travel", "clever-rockets-burn", @@ -192,12 +194,15 @@ "few-clouds-shop", "few-mugs-fail", "few-teachers-know", + "few-walls-check", "few-zoos-own", "fifty-actors-agree", "fifty-masks-give", "fifty-rice-wait", "fifty-steaks-float", "fifty-toys-invite", + "five-maps-reflect", + "five-shirts-run", "five-tigers-search", "flat-feet-visit", "flat-ghosts-fly", @@ -243,6 +248,7 @@ "fuzzy-donuts-provide", "gentle-dolls-juggle", "gentle-eagles-walk", + "gentle-needles-train", "gentle-sheep-hug", "gentle-spies-happen", "gentle-ties-fetch", @@ -273,17 +279,20 @@ "great-fans-unite", "great-icons-retire", "great-plums-pretend", + "green-baboons-sip", "green-eggs-approve", "green-fishes-lie", "green-hounds-play", "green-snails-tickle", "green-tigers-judge", "green-walls-clap", + "green-windows-tap", "grumpy-avocados-fetch", "grumpy-insects-sleep", "grumpy-jars-sparkle", "happy-beds-scream", "happy-dogs-jump", + "happy-dolls-joke", "happy-lobsters-lick", "happy-moles-live", "happy-planets-rest", @@ -337,6 +346,7 @@ "itchy-terms-guess", "khaki-cheetahs-refuse", "khaki-cooks-develop", + "khaki-donkeys-jump", "khaki-ligers-sing", "khaki-mails-draw", "khaki-mails-scream", @@ -375,6 +385,7 @@ "light-humans-hang", "light-penguins-invent", "light-pens-watch", + "light-tigers-smoke", "little-ligers-exist", "little-pans-jog", "little-seals-reflect", @@ -418,6 +429,7 @@ "mighty-files-hammer", "mighty-frogs-obey", "mighty-paws-smash", + "mighty-poets-fix", "mighty-shoes-nail", "modern-apricots-promise", "modern-fishes-double", @@ -477,6 +489,7 @@ "olive-cobras-wonder", "olive-forks-grin", "olive-kangaroos-brake", + "olive-llamas-warn", "olive-mice-fix", "olive-moons-act", "olive-seals-sell", @@ -487,6 +500,7 @@ "orange-dingos-poke", "orange-laws-drop", "orange-masks-exercise", + "orange-sheep-exist", "orange-yaks-protect", "orange-zoos-heal", "perfect-actors-bake", @@ -528,6 +542,7 @@ "proud-queens-sniff", "purple-dragons-peel", "quick-eagles-sit", + "quick-paws-wash", "quick-pumpkins-study", "quiet-apricots-dream", "quiet-berries-end", @@ -536,6 +551,7 @@ "quiet-cobras-smile", "quiet-crabs-nail", "quiet-timers-speak", + "rare-ears-agree", "rare-insects-tell", "rare-mirrors-act", "rare-pears-whisper", @@ -547,6 +563,7 @@ "red-doors-own", "red-feet-worry", "red-kings-draw", + "red-maps-nail", "red-poets-study", "red-pots-pretend", "rich-cobras-exist", @@ -586,6 +603,7 @@ "seven-hornets-smile", "seven-jobs-sniff", "seven-masks-end", + "seven-news-live", "seven-ravens-check", "shaggy-cameras-live", "shaggy-comics-jog", @@ -604,6 +622,7 @@ "shiny-rats-heal", "shiny-shrimps-march", "shiny-starfishes-cross", + "shiny-wombats-argue", "short-buses-camp", "short-countries-rush", "short-starfishes-beg", @@ -622,10 +641,12 @@ "silver-points-approve", "silver-sheep-knock", "six-apes-peel", + "six-beans-laugh", "six-bears-trade", "six-boats-shave", "six-chicken-kneel", "six-gorillas-obey", + "six-moons-invent", "six-vans-add", "sixty-items-crash", "sixty-numbers-hope", @@ -636,6 +657,7 @@ "slimy-clouds-talk", "slimy-hairs-impress", "slimy-laws-explode", + "slimy-news-help", "slimy-onions-approve", "slimy-walls-draw", "slow-beds-shave", @@ -798,6 +820,7 @@ "twenty-gifts-develop", "two-brooms-fail", "two-candles-move", + "two-cats-approve", "two-dogs-accept", "two-dragons-yell", "two-falcons-buy", @@ -818,7 +841,9 @@ "weak-frogs-bow", "weak-terms-destroy", "wet-bats-exercise", + "wet-donkeys-fry", "wet-games-fly", + "wet-pears-buy", "wet-pears-remain", "wet-wombats-repeat", "wicked-bikes-matter", diff --git a/.changeset/quick-paws-wash.md b/.changeset/quick-paws-wash.md new file mode 100644 index 0000000000..e93b68a0ca --- /dev/null +++ b/.changeset/quick-paws-wash.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: only traverse trailing static nodes during hydration diff --git a/.changeset/rare-ears-agree.md b/.changeset/rare-ears-agree.md new file mode 100644 index 0000000000..392d32c786 --- /dev/null +++ b/.changeset/rare-ears-agree.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +chore: update client check for smaller bundle size diff --git a/.changeset/red-maps-nail.md b/.changeset/red-maps-nail.md new file mode 100644 index 0000000000..731a863440 --- /dev/null +++ b/.changeset/red-maps-nail.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: better generated each block code in SSR mode diff --git a/.changeset/seven-news-live.md b/.changeset/seven-news-live.md new file mode 100644 index 0000000000..cfe6f3bc33 --- /dev/null +++ b/.changeset/seven-news-live.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure event currentTarget is reset after propagation logic diff --git a/.changeset/shiny-wombats-argue.md b/.changeset/shiny-wombats-argue.md new file mode 100644 index 0000000000..b35f1cf304 --- /dev/null +++ b/.changeset/shiny-wombats-argue.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: correctly hydrate empty raw blocks diff --git a/.changeset/six-beans-laugh.md b/.changeset/six-beans-laugh.md new file mode 100644 index 0000000000..f069501d9f --- /dev/null +++ b/.changeset/six-beans-laugh.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: prevent binding to imports diff --git a/.changeset/six-moons-invent.md b/.changeset/six-moons-invent.md new file mode 100644 index 0000000000..21bbdbad32 --- /dev/null +++ b/.changeset/six-moons-invent.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: make internal sources ownerless diff --git a/.changeset/slimy-news-help.md b/.changeset/slimy-news-help.md new file mode 100644 index 0000000000..a5e3e66ee6 --- /dev/null +++ b/.changeset/slimy-news-help.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: never abort bidirectional transitions diff --git a/.changeset/two-cats-approve.md b/.changeset/two-cats-approve.md new file mode 100644 index 0000000000..7756dfdd67 --- /dev/null +++ b/.changeset/two-cats-approve.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: repair `href` attribute mismatches diff --git a/.changeset/wet-donkeys-fry.md b/.changeset/wet-donkeys-fry.md new file mode 100644 index 0000000000..5ebba7a29b --- /dev/null +++ b/.changeset/wet-donkeys-fry.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: join text nodes separated by comments diff --git a/.changeset/wet-pears-buy.md b/.changeset/wet-pears-buy.md new file mode 100644 index 0000000000..b4cf666950 --- /dev/null +++ b/.changeset/wet-pears-buy.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: allow non-synchronous legacy component instantiation diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3c8b3955c..fbdd1e420c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,9 +29,9 @@ jobs: os: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: pnpm @@ -44,9 +44,9 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18 cache: pnpm @@ -64,9 +64,9 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18 cache: pnpm diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f07177f24f..a17f49bbeb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,13 +18,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits fetch-depth: 0 - uses: pnpm/action-setup@v4 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18.x cache: pnpm diff --git a/.prettierignore b/.prettierignore index 0550f0a2df..410e22d4ec 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,12 +2,12 @@ # see: https://github.com/sveltejs/svelte/pull/9609 documentation/docs/05-misc/03-typescript.md -# The following are all duplicated with prettierignore configs in the packages, -# which is necessary because of https://github.com/prettier/prettier-vscode/issues/3424 packages/**/dist/*.js packages/**/build/*.js packages/**/npm/**/* packages/**/config/*.js + +# packages/svelte packages/svelte/messages/**/*.md packages/svelte/src/compiler/errors.js packages/svelte/src/compiler/warnings.js @@ -17,6 +17,7 @@ packages/svelte/src/internal/shared/errors.js packages/svelte/src/internal/shared/warnings.js packages/svelte/src/internal/server/errors.js packages/svelte/tests/migrate/samples/*/output.svelte +packages/svelte/tests/**/*.svelte packages/svelte/tests/**/_expected* packages/svelte/tests/**/_actual* packages/svelte/tests/**/expected* @@ -29,6 +30,7 @@ packages/svelte/compiler/index.js playgrounds/sandbox/input/**.svelte playgrounds/sandbox/output +# sites/svelte.dev sites/svelte.dev/static/svelte-app.json sites/svelte.dev/scripts/svelte-app/ sites/svelte.dev/src/routes/_components/Supporters/contributors.jpg diff --git a/.vscode/launch.json b/.vscode/launch.json index fc593c0d06..142965ada2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,22 +1,6 @@ { "version": "0.2.0", "configurations": [ - { - "type": "chrome", - "request": "launch", - "name": "Playground: Browser", - "url": "http://localhost:10001" - }, - { - "type": "node", - "request": "launch", - "runtimeArgs": ["--watch"], - "name": "Playground: Server", - "outputCapture": "std", - "program": "start.js", - "cwd": "${workspaceFolder}/playgrounds/demo", - "cascadeTerminateToConfigurations": ["Playground: Browser"] - }, { "type": "node", "request": "launch", @@ -26,11 +10,5 @@ "NODE_OPTIONS": "--stack-trace-limit=10000" } } - ], - "compounds": [ - { - "name": "Playground: Full", - "configurations": ["Playground: Server", "Playground: Browser"] - } ] } diff --git a/benchmarking/benchmarks/kairo/kairo_avoidable.js b/benchmarking/benchmarks/kairo/kairo_avoidable.js index 108f79458c..76bd4c72e3 100644 --- a/benchmarking/benchmarks/kairo/kairo_avoidable.js +++ b/benchmarking/benchmarks/kairo/kairo_avoidable.js @@ -3,7 +3,7 @@ import * as $ from '../../../packages/svelte/src/internal/client/index.js'; import { busy } from './util.js'; function setup() { - let head = $.source(0); + let head = $.state(0); let computed1 = $.derived(() => $.get(head)); let computed2 = $.derived(() => ($.get(computed1), 0)); let computed3 = $.derived(() => (busy(), $.get(computed2) + 1)); // heavy computation diff --git a/benchmarking/benchmarks/kairo/kairo_broad.js b/benchmarking/benchmarks/kairo/kairo_broad.js index 06ce3cd7b5..d7b37d153c 100644 --- a/benchmarking/benchmarks/kairo/kairo_broad.js +++ b/benchmarking/benchmarks/kairo/kairo_broad.js @@ -2,7 +2,7 @@ import { assert, fastest_test } from '../../utils.js'; import * as $ from '../../../packages/svelte/src/internal/client/index.js'; function setup() { - let head = $.source(0); + let head = $.state(0); let last = head; let counter = 0; diff --git a/benchmarking/benchmarks/kairo/kairo_deep.js b/benchmarking/benchmarks/kairo/kairo_deep.js index ac4ac5641b..cc29940738 100644 --- a/benchmarking/benchmarks/kairo/kairo_deep.js +++ b/benchmarking/benchmarks/kairo/kairo_deep.js @@ -5,7 +5,7 @@ let len = 50; const iter = 50; function setup() { - let head = $.source(0); + let head = $.state(0); let current = head; for (let i = 0; i < len; i++) { let c = current; diff --git a/benchmarking/benchmarks/kairo/kairo_diamond.js b/benchmarking/benchmarks/kairo/kairo_diamond.js index 09d65cd89a..0492454966 100644 --- a/benchmarking/benchmarks/kairo/kairo_diamond.js +++ b/benchmarking/benchmarks/kairo/kairo_diamond.js @@ -4,7 +4,7 @@ import * as $ from '../../../packages/svelte/src/internal/client/index.js'; let width = 5; function setup() { - let head = $.source(0); + let head = $.state(0); let current = []; for (let i = 0; i < width; i++) { current.push( diff --git a/benchmarking/benchmarks/kairo/kairo_mux.js b/benchmarking/benchmarks/kairo/kairo_mux.js index 903b8d3758..769e14c43e 100644 --- a/benchmarking/benchmarks/kairo/kairo_mux.js +++ b/benchmarking/benchmarks/kairo/kairo_mux.js @@ -2,7 +2,7 @@ import { assert, fastest_test } from '../../utils.js'; import * as $ from '../../../packages/svelte/src/internal/client/index.js'; function setup() { - let heads = new Array(100).fill(null).map((_) => $.source(0)); + let heads = new Array(100).fill(null).map((_) => $.state(0)); const mux = $.derived(() => { return Object.fromEntries(heads.map((h) => $.get(h)).entries()); }); diff --git a/benchmarking/benchmarks/kairo/kairo_repeated.js b/benchmarking/benchmarks/kairo/kairo_repeated.js index ef9c284ad0..2416f89dfd 100644 --- a/benchmarking/benchmarks/kairo/kairo_repeated.js +++ b/benchmarking/benchmarks/kairo/kairo_repeated.js @@ -4,7 +4,7 @@ import * as $ from '../../../packages/svelte/src/internal/client/index.js'; let size = 30; function setup() { - let head = $.source(0); + let head = $.state(0); let current = $.derived(() => { let result = 0; for (let i = 0; i < size; i++) { diff --git a/benchmarking/benchmarks/kairo/kairo_triangle.js b/benchmarking/benchmarks/kairo/kairo_triangle.js index 0696efb39e..ee9311c96a 100644 --- a/benchmarking/benchmarks/kairo/kairo_triangle.js +++ b/benchmarking/benchmarks/kairo/kairo_triangle.js @@ -11,7 +11,7 @@ function count(number) { } function setup() { - let head = $.source(0); + let head = $.state(0); let current = head; let list = []; for (let i = 0; i < width; i++) { diff --git a/benchmarking/benchmarks/kairo/kairo_unstable.js b/benchmarking/benchmarks/kairo/kairo_unstable.js index 3e7120d6d2..b05fc0745a 100644 --- a/benchmarking/benchmarks/kairo/kairo_unstable.js +++ b/benchmarking/benchmarks/kairo/kairo_unstable.js @@ -2,7 +2,7 @@ import { assert, fastest_test } from '../../utils.js'; import * as $ from '../../../packages/svelte/src/internal/client/index.js'; function setup() { - let head = $.source(0); + let head = $.state(0); const double = $.derived(() => $.get(head) * 2); const inverse = $.derived(() => -$.get(head)); let current = $.derived(() => { diff --git a/benchmarking/benchmarks/kairo/util.js b/benchmarking/benchmarks/kairo/util.js index 5c73e99eec..75e3641ab9 100644 --- a/benchmarking/benchmarks/kairo/util.js +++ b/benchmarking/benchmarks/kairo/util.js @@ -1,7 +1,6 @@ - export function busy() { - let a = 0; - for (let i = 0; i < 1_00; i++) { - a++; - } + let a = 0; + for (let i = 0; i < 1_00; i++) { + a++; + } } diff --git a/benchmarking/benchmarks/mol_bench.js b/benchmarking/benchmarks/mol_bench.js index adb4aceb23..a962f5e148 100644 --- a/benchmarking/benchmarks/mol_bench.js +++ b/benchmarking/benchmarks/mol_bench.js @@ -20,8 +20,8 @@ const numbers = Array.from({ length: 5 }, (_, i) => i); function setup() { let res = []; - const A = $.source(0); - const B = $.source(0); + const A = $.state(0); + const B = $.state(0); const C = $.derived(() => ($.get(A) % 2) + ($.get(B) % 2)); const D = $.derived(() => numbers.map((i) => i + ($.get(A) % 2) - ($.get(B) % 2))); D.equals = function (/** @type {number[]} */ l) { diff --git a/benchmarking/benchmarks/sbench.js b/benchmarking/benchmarks/sbench.js index 9bc0cee83c..4c52265838 100644 --- a/benchmarking/benchmarks/sbench.js +++ b/benchmarking/benchmarks/sbench.js @@ -9,7 +9,7 @@ const COUNT = 1e5; */ function create_data_signals(n, sources) { for (let i = 0; i < n; i++) { - sources[i] = $.source(i); + sources[i] = $.state(i); } return sources; } diff --git a/documentation/docs/03-runes/02-side-effects.md b/documentation/docs/03-runes/02-side-effects.md index f4bc8ef947..4cef5228ca 100644 --- a/documentation/docs/03-runes/02-side-effects.md +++ b/documentation/docs/03-runes/02-side-effects.md @@ -33,6 +33,8 @@ To run _side-effects_ when the component is mounted to the DOM, and when values The function passed to `$effect` will run when the component mounts, and will re-run after any changes to the values it reads that were declared with `$state` or `$derived` (including those passed in with `$props`). Re-runs are batched (i.e. changing `color` and `size` in the same moment won't cause two separate runs), and happen after any DOM updates have been applied. +You can place `$effect` anywhere, not just at the top level of a component, as long as it is called during component initialization (or while a parent effect is active). It is then tied to the lifecycle of the component (or parent effect) and will therefore destroy itself when the component unmounts (or the parent effect is destroyed). + You can return a function from `$effect`, which will run immediately before the effect re-runs, and before it is destroyed ([demo](/#H4sIAAAAAAAAE42SzW6DMBCEX2Vl5RDaVCQ9JoDUY--9lUox9lKsGBvZC1GEePcaKPnpqSe86_m0M2t6ViqNnu0_e2Z4jWzP3pqGbRhdmrHwHWrCUHvbOjF2Ei-caijLTU4aCYRtDUEKK0-ccL2NDstNrbRWHoU10t8Eu-121gTVCssSBa3XEaQZ9GMrpziGj0p5OAccCgSHwmEgJZwrNNihg6MyhK7j-gii4uYb_YyGUZ5guQwzPdL7b_U4ZNSOvp9T2B3m1rB5cLx4zMkhtc7AHz7YVCVwEFzrgosTBMuNs52SKDegaPbvWnMH8AhUXaNUIY6-hHCldQhUIcyLCFlfAuHvkCKaYk8iYevGGgy2wyyJnpy9oLwG0sjdNe2yhGhJN32HsUzi2xOapNpl_bSLIYnDeeoVLZE1YI3QSpzSfo7-8J5PKbwOmdf2jC6JZyD7HxpPaMk93aHhF6utVKVCyfbkWhy-hh9Z3o_2nQIAAA==)). ```svelte diff --git a/eslint.config.js b/eslint.config.js index 60a1bb7e48..ad8c5a3597 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -39,7 +39,8 @@ export default [ { languageOptions: { parserOptions: { - project: true + projectService: true, + tsconfigRootDir: import.meta.dirname } }, plugins: { @@ -64,10 +65,14 @@ export default [ } }, { - files: ['playgrounds/**/*'], + // If you get an error along the lines of "@typescript-eslint/await-thenable needs a project service configured", then that likely means + // that eslint rules that need to be type-aware run through a Svelte file which seems unsupported at the moment. In that case, ensure that + // these are excluded to run on Svelte files. + files: ['**/*.svelte'], rules: { - 'lube/svelte-naming-convention': 'off', - 'no-console': 'off' + '@typescript-eslint/await-thenable': 'off', + '@typescript-eslint/prefer-promise-reject-errors': 'off', + '@typescript-eslint/require-await': 'off' } }, { @@ -87,6 +92,12 @@ export default [ 'packages/svelte/src/internal/client/warnings.js', 'packages/svelte/src/internal/shared/warnings.js', 'packages/svelte/compiler/index.js', + // stuff we don't want to lint + 'benchmarking/**', + 'coverage/**', + 'playgrounds/sandbox/**', + // exclude top level config files + '*.config.js', // documentation can contain invalid examples 'documentation', // contains a fork of the REPL which doesn't adhere to eslint rules diff --git a/package.json b/package.json index 570b3bdcf5..580085e7db 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "build:sites": "pnpm -r --filter=./sites/* build", "preview-site": "npm run build --prefix sites/svelte-5-preview", "check": "cd packages/svelte && pnpm build && cd ../../ && pnpm -r check", - "lint": "pnpm -r lint && prettier --check documentation", - "format": "pnpm -r format && prettier --check --write documentation", + "lint": "eslint && prettier --check .", + "format": "prettier --write .", "test": "vitest run", "test-output": "vitest run --coverage --reporter=json --outputFile=sites/svelte-5-preview/src/routes/status/results.json", "changeset:version": "changeset version && pnpm -r generate:version && git add --all", @@ -33,18 +33,18 @@ "@sveltejs/eslint-config": "^8.0.1", "@svitejs/changesets-changelog-github-compact": "^1.1.0", "@types/node": "^20.11.5", - "@vitest/coverage-v8": "^1.2.1", - "eslint": "^9.6.0", + "@vitest/coverage-v8": "^2.0.5", + "eslint": "^9.9.1", "eslint-plugin-lube": "^0.4.3", - "jsdom": "22.0.0", - "playwright": "^1.41.1", + "jsdom": "25.0.0", + "playwright": "^1.46.1", "prettier": "^3.2.4", "prettier-plugin-svelte": "^3.1.2", "svelte": "workspace:^", - "typescript": "^5.5.2", - "typescript-eslint": "^8.0.0-alpha.34", + "typescript": "^5.5.4", + "typescript-eslint": "^8.2.0", "v8-natives": "^1.2.5", - "vitest": "^1.2.1" + "vitest": "^2.0.5" }, "pnpm": { "overrides": { diff --git a/packages/svelte/.prettierignore b/packages/svelte/.prettierignore deleted file mode 100644 index c9c002f671..0000000000 --- a/packages/svelte/.prettierignore +++ /dev/null @@ -1,22 +0,0 @@ -dist/*.js -build/*.js -npm/**/* -config/*.js -messages/**/*.md -src/compiler/errors.js -src/compiler/warnings.js -src/internal/client/errors.js -src/internal/client/warnings.js -src/internal/shared/errors.js -src/internal/shared/warnings.js -src/internal/server/errors.js -tests/**/*.svelte -tests/**/_expected* -tests/**/_actual* -tests/**/expected* -tests/**/_output -tests/**/shards/*.test.js -tests/hydration/samples/*/_expected.html -tests/hydration/samples/*/_override.html -types -compiler/index.js diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index d0c47fd678..a81cadf2b1 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,91 @@ # svelte +## 5.0.0-next.242 + +### Patch Changes + +- fix: insert comment before text in an each block, to prevent glued nodes ([#13073](https://github.com/sveltejs/svelte/pull/13073)) + +- feat: better generated each block code in SSR mode ([#13060](https://github.com/sveltejs/svelte/pull/13060)) + +## 5.0.0-next.241 + +### Patch Changes + +- fix: prevent div/0 when generating transition keyframes ([#13058](https://github.com/sveltejs/svelte/pull/13058)) + +- fix: error on invalid element name ([#13057](https://github.com/sveltejs/svelte/pull/13057)) + +- fix: better compile errors for invalid tag names/placement ([#13045](https://github.com/sveltejs/svelte/pull/13045)) + +- fix: ensure event currentTarget is reset after propagation logic ([#13042](https://github.com/sveltejs/svelte/pull/13042)) + +## 5.0.0-next.240 + +### Patch Changes + +- fix: use WAAPI to control timing of JS-based animations ([#13018](https://github.com/sveltejs/svelte/pull/13018)) + +- fix: prevent binding to imports ([#13035](https://github.com/sveltejs/svelte/pull/13035)) + +- fix: never abort bidirectional transitions ([#13018](https://github.com/sveltejs/svelte/pull/13018)) + +## 5.0.0-next.239 + +### Patch Changes + +- fix: properly handle proxied array length mutations ([#13026](https://github.com/sveltejs/svelte/pull/13026)) + +- fix: repair `href` attribute mismatches ([#13032](https://github.com/sveltejs/svelte/pull/13032)) + +## 5.0.0-next.238 + +### Patch Changes + +- fix: always return true from `deleteProperty` trap ([#13008](https://github.com/sveltejs/svelte/pull/13008)) + +- fix: handle deletions of previously-unread state proxy properties ([#13008](https://github.com/sveltejs/svelte/pull/13008)) + +- fix: make internal sources ownerless ([#13013](https://github.com/sveltejs/svelte/pull/13013)) + +- fix: join text nodes separated by comments ([#13009](https://github.com/sveltejs/svelte/pull/13009)) + +## 5.0.0-next.237 + +### Patch Changes + +- breaking: throw error if derived creates state and then depends on it ([#12985](https://github.com/sveltejs/svelte/pull/12985)) + +- fix: ensure assignments to state field inside constructor trigger effects ([#12985](https://github.com/sveltejs/svelte/pull/12985)) + +- fix: ensure $inspect works with SvelteMap and SvelteSet ([#12994](https://github.com/sveltejs/svelte/pull/12994)) + +- chore: default options.filename to "(unknown)" ([#12997](https://github.com/sveltejs/svelte/pull/12997)) + +- feat: allow non-synchronous legacy component instantiation ([#12970](https://github.com/sveltejs/svelte/pull/12970)) + +## 5.0.0-next.236 + +### Patch Changes + +- fix: properly transform destructured `$derived.by` declarations ([#12984](https://github.com/sveltejs/svelte/pull/12984)) + +## 5.0.0-next.235 + +### Patch Changes + +- chore: update client check for smaller bundle size ([#12975](https://github.com/sveltejs/svelte/pull/12975)) + +- fix: correctly hydrate empty raw blocks ([#12979](https://github.com/sveltejs/svelte/pull/12979)) + +## 5.0.0-next.234 + +### Patch Changes + +- fix: allow deleting non-existent `$restProps` properties ([#12971](https://github.com/sveltejs/svelte/pull/12971)) + +- feat: only traverse trailing static nodes during hydration ([#12935](https://github.com/sveltejs/svelte/pull/12935)) + ## 5.0.0-next.233 ### Patch Changes diff --git a/packages/svelte/knip.json b/packages/svelte/knip.json new file mode 100644 index 0000000000..7a27a64a91 --- /dev/null +++ b/packages/svelte/knip.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://unpkg.com/knip@5/schema.json", + "entry": [ + "src/*/index.js", + "src/index-client.ts", + "src/index-server.ts", + "src/index.d.ts", + "tests/**/*.js", + "tests/**/*.ts", + "!tests/**/*.svelte", + "!tests/**/*.svelte.js", + "!tests/**/_output", + "!tests/runtime-browser/driver.js", + "!tests/runtime-browser/driver-ssr.js", + "!tests/types/component.ts" + ], + "project": ["src/**"] +} diff --git a/packages/svelte/messages/client-errors/errors.md b/packages/svelte/messages/client-errors/errors.md index ee05f6e664..4e8af2e6b4 100644 --- a/packages/svelte/messages/client-errors/errors.md +++ b/packages/svelte/messages/client-errors/errors.md @@ -72,10 +72,10 @@ > Cannot set prototype of `$state` object -## state_unsafe_mutation +## state_unsafe_local_read -> Updating state inside a derived is forbidden. If the value should not be reactive, declare it without `$state` +> Reading state that was created inside the same derived is forbidden. Consider using `untrack` to read locally created state -## svelte_component_invalid_this_value +## state_unsafe_mutation -> The `this={...}` property of a `` must be a Svelte component, if defined +> Updating state inside a derived is forbidden. If the value should not be reactive, declare it without `$state` diff --git a/packages/svelte/messages/compile-errors/template.md b/packages/svelte/messages/compile-errors/template.md index 49a422ecde..a71716b06d 100644 --- a/packages/svelte/messages/compile-errors/template.md +++ b/packages/svelte/messages/compile-errors/template.md @@ -100,10 +100,6 @@ > This type of directive is not valid on components -## component_invalid_name - -> Component name must be a valid variable name or dot notation expression - ## const_tag_cycle > Cyclical dependency detected: %cycle% @@ -136,10 +132,6 @@ > `` attempted to close element that was already automatically closed by `<%reason%>` (cannot nest `<%reason%>` inside `<%name%>`) -## element_invalid_tag_name - -> Expected valid tag name - ## element_unclosed > `<%name%>` was left open @@ -282,6 +274,10 @@ HTML restricts where certain elements can appear. In case of a violation the bro > A component can have a single top-level `