feat: simplify derived object destructuring (#12781)

* simplify derived object destructuring

* add test for destructuring an array

* add changeset

* shorter temp variable name

* skip intermediate derived for simple cases

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/12786/head
ottomated 5 months ago committed by GitHub
parent d6e26c0953
commit 7de3e3b703
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
feat: simplify derived object destructuring

@ -171,39 +171,29 @@ export function VariableDeclaration(node, context) {
) )
); );
} else { } else {
const bindings = context.state.scope.get_bindings(declarator); const bindings = extract_paths(declarator.id);
const object_id = context.state.scope.generate('derived_object');
const values_id = context.state.scope.generate('derived_values'); const init = /** @type {CallExpression} */ (declarator.init);
declarations.push(
b.declarator( /** @type {Identifier} */
b.id(object_id), let id;
b.call('$.derived', rune === '$derived.by' ? value : b.thunk(value)) let rhs = value;
)
); if (init.arguments[0].type === 'Identifier') {
declarations.push( id = init.arguments[0];
b.declarator( } else {
b.id(values_id), id = b.id(context.state.scope.generate('$$d'));
b.call( rhs = b.call('$.get', id);
'$.derived',
b.thunk( declarations.push(
b.block([ b.declarator(id, b.call('$.derived', rune === '$derived.by' ? value : b.thunk(value)))
b.let(declarator.id, b.call('$.get', b.id(object_id))), );
b.return(b.array(bindings.map((binding) => binding.node))) }
])
)
)
)
);
for (let i = 0; i < bindings.length; i++) { for (let i = 0; i < bindings.length; i++) {
const binding = bindings[i]; const binding = bindings[i];
declarations.push( declarations.push(
b.declarator( b.declarator(binding.node, b.call('$.derived', b.thunk(binding.expression(rhs))))
binding.node,
b.call(
'$.derived',
b.thunk(b.member(b.call('$.get', b.id(values_id)), b.literal(i), true))
)
)
); );
} }
} }

@ -1,5 +1,5 @@
import { test } from '../../test'; import { test } from '../../test';
export default test({ export default test({
html: `true 1 2 baz` html: `true 1 2 baz 1 2 3`
}); });

@ -1,6 +1,9 @@
<script> <script>
let stuff = $state({ foo: true, bar: [1, 2, {baz: 'baz'}] }); let stuff = $state({ foo: true, bar: [1, 2, {baz: 'baz'}] });
let { foo, bar: [a, b, { baz }]} = $derived(stuff); let { foo, bar: [a, b, { baz }]} = $derived(stuff);
let stuff2 = $state([1, 2, 3]);
let [d, e, f] = $derived(stuff2);
</script> </script>
{foo} {a} {b} {baz} {foo} {a} {b} {baz} {d} {e} {f}
Loading…
Cancel
Save