Skip to content

Commit c3b56a1

Browse files
authored
handle destructuring to a store value (#5452)
1 parent 6e0cd9b commit c3b56a1

File tree

6 files changed

+95
-38
lines changed

6 files changed

+95
-38
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
* Fix destructuring into store values ([#5449](https://github.com/sveltejs/svelte/issues/5449))
56
* Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451))
67

78
## 3.26.0

src/compiler/compile/render_dom/invalidate.ts

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,47 +36,46 @@ export function invalidate(renderer: Renderer, scope: Scope, node: Node, names:
3636
return renderer.invalidate(variable.name, undefined, main_execution_context);
3737
}
3838

39-
if (head) {
40-
component.has_reactive_assignments = true;
41-
42-
if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) {
43-
return get_invalidated(head, node);
44-
} else {
45-
const is_store_value = head.name[0] === '$' && head.name[1] !== '$';
46-
const extra_args = tail.map(variable => get_invalidated(variable)).filter(Boolean);
47-
48-
const pass_value = (
49-
!main_execution_context &&
50-
(
51-
extra_args.length > 0 ||
52-
(node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') ||
53-
(node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier'))
54-
)
55-
);
39+
if (!head) {
40+
return node;
41+
}
5642

57-
if (pass_value) {
58-
extra_args.unshift({
59-
type: 'Identifier',
60-
name: head.name
61-
});
62-
}
43+
component.has_reactive_assignments = true;
6344

64-
let invalidate = is_store_value
65-
? x`@set_store_value(${head.name.slice(1)}, ${node}, ${head.name})`
66-
: !main_execution_context
67-
? x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})`
68-
: extra_args.length
69-
? [node, ...extra_args]
70-
: node;
45+
if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) {
46+
return get_invalidated(head, node);
47+
}
7148

72-
if (head.subscribable && head.reassigned) {
73-
const subscribe = `$$subscribe_${head.name}`;
74-
invalidate = x`${subscribe}(${invalidate})`;
75-
}
49+
const is_store_value = head.name[0] === '$' && head.name[1] !== '$';
50+
const extra_args = tail.map(variable => get_invalidated(variable)).filter(Boolean);
7651

77-
return invalidate;
52+
if (is_store_value) {
53+
return x`@set_store_value(${head.name.slice(1)}, ${node}, ${head.name}, ${extra_args})`;
54+
}
55+
56+
let invalidate;
57+
if (!main_execution_context) {
58+
const pass_value = (
59+
extra_args.length > 0 ||
60+
(node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') ||
61+
(node.type === 'UpdateExpression' && (!node.prefix || node.argument.type !== 'Identifier'))
62+
);
63+
if (pass_value) {
64+
extra_args.unshift({
65+
type: 'Identifier',
66+
name: head.name
67+
});
7868
}
69+
invalidate = x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})`;
70+
} else {
71+
// skip `$$invalidate` if it is in the main execution context
72+
invalidate = extra_args.length ? [node, ...extra_args] : node;
73+
}
74+
75+
if (head.subscribable && head.reassigned) {
76+
const subscribe = `$$subscribe_${head.name}`;
77+
invalidate = x`${subscribe}(${invalidate})`;
7978
}
8079

81-
return node;
80+
return invalidate;
8281
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// destructure to store value
2+
export default {
3+
skip_if_ssr: true, // pending https://github.com/sveltejs/svelte/issues/3582
4+
html: `<h1>2 2 xxx 5 6 9 10 2</h1>`,
5+
async test({ assert, target, component }) {
6+
await component.update();
7+
assert.htmlEqual(target.innerHTML, `<h1>11 11 yyy 12 13 14 15 11</h1>`);
8+
}
9+
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script>
2+
import { writable } from 'svelte/store';
3+
4+
let eid = writable(1);
5+
let foo;
6+
const u = writable(2);
7+
const v = writable(3);
8+
const w = writable(4);
9+
const x = writable(5);
10+
const y = writable(6);
11+
[$u, $v, $w] = [
12+
{id: eid = writable(foo = 2), name: 'xxx'},
13+
5,
14+
6
15+
];
16+
({ a: $x, b: $y } = { a: 9, b: 10 });
17+
$: z = $u.id;
18+
19+
export function update() {
20+
[$u, $v, $w] = [
21+
{id: eid = writable(foo = 11), name: 'yyy'},
22+
12,
23+
13
24+
];
25+
({ a: $x, b: $y } = { a: 14, b: 15 });
26+
}
27+
</script>
28+
29+
<h1>{foo} {$eid} {$u.name} {$v} {$w} {$x} {$y} {$z}</h1>
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
// destructure to store
12
export default {
2-
html: `<h1>2 2 xxx 5 6</h1>`
3+
html: `<h1>2 2 xxx 5 6 9 10 2</h1>`,
4+
skip_if_ssr: true,
5+
async test({ assert, target, component }) {
6+
await component.update();
7+
assert.htmlEqual(target.innerHTML, `<h1>11 11 yyy 12 13 14 15 11</h1>`);
8+
}
39
};

test/runtime/samples/reactive-assignment-in-complex-declaration-with-store/main.svelte

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,24 @@
66
let u;
77
let v;
88
let w;
9+
let x;
10+
let y;
911
[u, v, w] = [
1012
{id: eid = writable(foo = 2), name: 'xxx'},
1113
5,
1214
writable(6)
1315
];
16+
({ a: x, b: y } = { a: writable(9), b: writable(10) });
17+
$: z = u.id;
18+
19+
export function update() {
20+
[u, v, w] = [
21+
{id: eid = writable(foo = 11), name: 'yyy'},
22+
12,
23+
writable(13)
24+
];
25+
({ a: x, b: y } = { a: writable(14), b: writable(15) });
26+
}
1427
</script>
1528

16-
<h1>{foo} {$eid} {u.name} {v} {$w}</h1>
29+
<h1>{foo} {$eid} {u.name} {v} {$w} {$x} {$y} {$z}</h1>

0 commit comments

Comments
 (0)