Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/mighty-balloons-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: allow async destructured deriveds
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,14 @@ export function VariableDeclaration(node, context) {
context.state.transform[id.name] = { read: get_value };

const expression = /** @type {Expression} */ (context.visit(b.thunk(value)));
const call = b.call('$.derived', expression);
return b.declarator(
id,
dev ? b.call('$.tag', call, b.literal('[$state iterable]')) : call
);
let call = b.call('$.derived', expression);

if (dev) {
const label = `[$state ${declarator.id.type === 'ArrayPattern' ? 'iterable' : 'object'}]`;
call = b.call('$.tag', call, b.literal(label));
}

return b.declarator(id, call);
}),
...paths.map((path) => {
const value = /** @type {Expression} */ (context.visit(path.expression));
Expand Down Expand Up @@ -228,19 +231,37 @@ export function VariableDeclaration(node, context) {
}
} else {
const init = /** @type {CallExpression} */ (declarator.init);
let expression = /** @type {Expression} */ (
context.visit(value, {
...context.state,
in_derived: rune === '$derived'
})
);

let rhs = value;

if (rune !== '$derived' || init.arguments[0].type !== 'Identifier') {
const id = b.id(context.state.scope.generate('$$d'));
let call = b.call('$.derived', rune === '$derived' ? b.thunk(expression) : expression);

rhs = b.call('$.get', id);

let expression = /** @type {Expression} */ (context.visit(value));
if (rune === '$derived') expression = b.thunk(expression);
const call = b.call('$.derived', expression);
declarations.push(
b.declarator(id, dev ? b.call('$.tag', call, b.literal('[$derived iterable]')) : call)
);
if (is_async) {
const location = dev && !is_ignored(init, 'await_waterfall') && locate_node(init);
call = b.call(
'$.async_derived',
b.thunk(expression, true),
location ? b.literal(location) : undefined
);
call = b.call(b.await(b.call('$.save', call)));
}

if (dev) {
const label = `[$derived ${declarator.id.type === 'ArrayPattern' ? 'iterable' : 'object'}]`;
call = b.call('$.tag', call, b.literal(label));
}

declarations.push(b.declarator(id, call));
}

const { inserts, paths } = extract_paths(declarator.id, rhs);
Expand All @@ -252,7 +273,18 @@ export function VariableDeclaration(node, context) {
const expression = /** @type {Expression} */ (context.visit(b.thunk(value)));
const call = b.call('$.derived', expression);
declarations.push(
b.declarator(id, dev ? b.call('$.tag', call, b.literal('[$derived iterable]')) : call)
b.declarator(
id,
dev
? b.call(
'$.tag',
call,
b.literal(
`[$derived ${declarator.id.type === 'ArrayPattern' ? 'iterable' : 'object'}]`
)
)
: call
)
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script>
let count = $state(1);

let { squared, cubed } = $derived(await {
squared: count ** 2,
cubed: count ** 3
});
</script>

<button onclick={() => count++}>increment</button>

<p>{count} ** 2 = {squared}</p>
<p>{count} ** 3 = {cubed}</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { tick } from 'svelte';
import { test } from '../../test';

export default test({
async test({ assert, target }) {
await tick();

const [increment] = target.querySelectorAll('button');

assert.htmlEqual(
target.innerHTML,
`
<button>increment</button>
<p>1 ** 2 = 1</p>
<p>1 ** 3 = 1</p>
`
);

increment.click();
await tick();

assert.htmlEqual(
target.innerHTML,
`
<button>increment</button>
<p>2 ** 2 = 4</p>
<p>2 ** 3 = 8</p>
`
);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
import Child from './Child.svelte';
</script>

<svelte:boundary>
<Child />

{#snippet pending()}
<p>pending</p>
{/snippet}
</svelte:boundary>
8 changes: 8 additions & 0 deletions svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// we need this so the VS Code extension doesn't yell at us
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, meant to commit this in a separate PR. oh well never mind

export default {
compilerOptions: {
experimental: {
async: true
}
}
};
Loading