Skip to content

Commit 696bb2e

Browse files
committed
merge main
2 parents 088a771 + aaeda65 commit 696bb2e

File tree

26 files changed

+445
-314
lines changed

26 files changed

+445
-314
lines changed

.changeset/cuddly-chefs-refuse.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: correctly match `:has()` selector during css pruning

.changeset/gold-hairs-jog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: allow global-like pseudo-selectors refinement

.changeset/hungry-dancers-tap.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
chore: don't distribute unused types definitions

documentation/docs/07-misc/99-faq.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ It will show up on hover.
4646
- You can use markdown here.
4747
- You can also use code blocks here.
4848
- Usage:
49-
```tsx
49+
```svelte
5050
<main name="Arethra">
5151
```
5252
-->

documentation/docs/98-reference/.generated/client-errors.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,27 @@ Reading state that was created inside the same derived is forbidden. Consider us
133133
```
134134
Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
135135
```
136+
137+
This error is thrown in a situation like this:
138+
139+
```svelte
140+
<script>
141+
let count = $state(0);
142+
let multiple = $derived.by(() => {
143+
const result = count * 2;
144+
if (result > 10) {
145+
count = 0;
146+
}
147+
return result;
148+
});
149+
</script>
150+
151+
<button onclick={() => count++}>{count} / {multiple}</button>
152+
```
153+
154+
Here, the `$derived` updates `count`, which is `$state` and therefore forbidden to do. It is forbidden because the reactive graph could become unstable as a result, leading to subtle bugs, like values being stale or effects firing in the wrong order. To prevent this, Svelte errors when detecting an update to a `$state` variable.
155+
156+
To fix this:
157+
- See if it's possible to refactor your `$derived` such that the update becomes unnecessary
158+
- Think about why you need to update `$state` inside a `$derived` in the first place. Maybe it's because you're using `bind:`, which leads you down a bad code path, and separating input and output path (by splitting it up to an attribute and an event, or by using [Function bindings](bind#Function-bindings)) makes it possible avoid the update
159+
- If it's unavoidable, you may need to use an [`$effect`]($effect) instead. This could include splitting parts of the `$derived` into an [`$effect`]($effect) which does the updates

packages/svelte/messages/client-errors/errors.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,27 @@ See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-long
8787
## state_unsafe_mutation
8888

8989
> Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
90+
91+
This error is thrown in a situation like this:
92+
93+
```svelte
94+
<script>
95+
let count = $state(0);
96+
let multiple = $derived.by(() => {
97+
const result = count * 2;
98+
if (result > 10) {
99+
count = 0;
100+
}
101+
return result;
102+
});
103+
</script>
104+
105+
<button onclick={() => count++}>{count} / {multiple}</button>
106+
```
107+
108+
Here, the `$derived` updates `count`, which is `$state` and therefore forbidden to do. It is forbidden because the reactive graph could become unstable as a result, leading to subtle bugs, like values being stale or effects firing in the wrong order. To prevent this, Svelte errors when detecting an update to a `$state` variable.
109+
110+
To fix this:
111+
- See if it's possible to refactor your `$derived` such that the update becomes unnecessary
112+
- Think about why you need to update `$state` inside a `$derived` in the first place. Maybe it's because you're using `bind:`, which leads you down a bad code path, and separating input and output path (by splitting it up to an attribute and an event, or by using [Function bindings](bind#Function-bindings)) makes it possible avoid the update
113+
- If it's unavoidable, you may need to use an [`$effect`]($effect) instead. This could include splitting parts of the `$derived` into an [`$effect`]($effect) which does the updates

packages/svelte/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
"node": ">=18"
1010
},
1111
"files": [
12+
"*.d.ts",
1213
"src",
1314
"!src/**/*.test.*",
15+
"!src/**/*.d.ts",
1416
"types",
1517
"compiler",
16-
"*.d.ts",
1718
"README.md"
1819
],
1920
"module": "src/index-client.js",

packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,13 @@ const css_visitors = {
133133

134134
node.metadata.is_global = node.selectors.length >= 1 && is_global(node);
135135

136-
if (node.selectors.length === 1) {
136+
if (
137+
node.selectors.length >= 1 &&
138+
node.selectors.every(
139+
(selector) =>
140+
selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector'
141+
)
142+
) {
137143
const first = node.selectors[0];
138144
node.metadata.is_global_like ||=
139145
(first.type === 'PseudoClassSelector' && first.name === 'host') ||

0 commit comments

Comments
 (0)