Merge branch 'main' into state-onchange

state-onchange
Rich Harris 6 months ago
commit a33ff30e2a

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: prevent state runes from being called with spread

@ -660,6 +660,12 @@ Cannot access a computed property of a rune
`%name%` is not a valid rune
```
### rune_invalid_spread
```
`%rune%` cannot be called with a spread argument
```
### rune_invalid_usage
```

@ -1,5 +1,17 @@
# svelte
## 5.25.2
### Patch Changes
- feat: migrate reassigned deriveds to `$derived` ([#15581](https://github.com/sveltejs/svelte/pull/15581))
## 5.25.1
### Patch Changes
- fix: prevent dev server from throwing errors when attempting to retrieve the proxied value of an iframe's contentWindow ([#15577](https://github.com/sveltejs/svelte/pull/15577))
## 5.25.0
### Minor Changes

@ -162,6 +162,10 @@ This turned out to be buggy and unpredictable, particularly when working with de
> `%name%` is not a valid rune
## rune_invalid_spread
> `%rune%` cannot be called with a spread argument
## rune_invalid_usage
> Cannot use `%rune%` rune in non-runes mode

@ -2,7 +2,7 @@
"name": "svelte",
"description": "Cybernetically enhanced web apps",
"license": "MIT",
"version": "5.25.0",
"version": "5.25.2",
"type": "module",
"types": "./types/index.d.ts",
"engines": {

@ -383,6 +383,16 @@ export function rune_invalid_name(node, name) {
e(node, 'rune_invalid_name', `\`${name}\` is not a valid rune\nhttps://svelte.dev/e/rune_invalid_name`);
}
/**
* `%rune%` cannot be called with a spread argument
* @param {null | number | NodeLike} node
* @param {string} rune
* @returns {never}
*/
export function rune_invalid_spread(node, rune) {
e(node, 'rune_invalid_spread', `\`${rune}\` cannot be called with a spread argument\nhttps://svelte.dev/e/rune_invalid_spread`);
}
/**
* Cannot use `%rune%` rune in non-runes mode
* @param {null | number | NodeLike} node

@ -952,7 +952,7 @@ const instance_script = {
const reassigned_bindings = bindings.filter((b) => b?.reassigned);
if (
reassigned_bindings.length === 0 &&
node.body.expression.right.type !== 'Literal' &&
!bindings.some((b) => b?.kind === 'store_sub') &&
node.body.expression.left.type !== 'MemberExpression'
) {

@ -17,6 +17,14 @@ export function CallExpression(node, context) {
const rune = get_rune(node, context.state.scope);
if (rune && rune !== '$inspect') {
for (const arg of node.arguments) {
if (arg.type === 'SpreadElement') {
e.rune_invalid_spread(node, rune);
}
}
}
switch (rune) {
case null:
if (!is_safe_identifier(node.callee, context.state.scope)) {

@ -483,8 +483,18 @@ function update_version(signal, d = 1) {
* @param {any} value
*/
export function get_proxied_value(value) {
if (value !== null && typeof value === 'object' && STATE_SYMBOL in value) {
return value[STATE_SYMBOL];
try {
if (value !== null && typeof value === 'object' && STATE_SYMBOL in value) {
return value[STATE_SYMBOL];
}
} catch {
// the above if check can throw an error if the value in question
// is the contentWindow of an iframe on another domain, in which
// case we want to just return the value (because it's definitely
// not a proxied value) so we don't break any JavaScript interacting
// with that iframe (such as various payment companies client side
// JavaScript libraries interacting with their iframes on the same
// domain)
}
return value;

@ -4,5 +4,5 @@
* The current version, as set in package.json.
* @type {string}
*/
export const VERSION = '5.25.0';
export const VERSION = '5.25.2';
export const PUBLIC_VERSION = '5';

@ -0,0 +1,10 @@
<script>
let name = 'world';
$: upper = name.toUpperCase();
</script>
<input bind:value={name} />
<input bind:value={upper} />
{upper}

@ -0,0 +1,10 @@
<script>
let name = $state('world');
let upper = $derived(name.toUpperCase());
</script>
<input bind:value={name} />
<input bind:value={upper} />
{upper}

@ -0,0 +1,14 @@
[
{
"code": "rune_invalid_spread",
"end": {
"column": 35,
"line": 3
},
"message": "`$derived.by` cannot be called with a spread argument",
"start": {
"column": 15,
"line": 3
}
}
]

@ -0,0 +1,4 @@
<script>
const args = [0];
const count = $derived.by(...args);
</script>

@ -0,0 +1,14 @@
[
{
"code": "rune_invalid_spread",
"end": {
"column": 32,
"line": 3
},
"message": "`$derived` cannot be called with a spread argument",
"start": {
"column": 15,
"line": 3
}
}
]

@ -0,0 +1,4 @@
<script>
const args = [0];
const count = $derived(...args);
</script>

@ -0,0 +1,14 @@
[
{
"code": "rune_invalid_spread",
"end": {
"column": 34,
"line": 3
},
"message": "`$state.raw` cannot be called with a spread argument",
"start": {
"column": 15,
"line": 3
}
}
]

@ -0,0 +1,4 @@
<script>
const args = [0];
const count = $state.raw(...args);
</script>

@ -0,0 +1,14 @@
[
{
"code": "rune_invalid_spread",
"end": {
"column": 30,
"line": 3
},
"message": "`$state` cannot be called with a spread argument",
"start": {
"column": 15,
"line": 3
}
}
]

@ -0,0 +1,4 @@
<script>
const args = [0];
const count = $state(...args);
</script>
Loading…
Cancel
Save