pull/18533/merge
Nic Polumeyv 1 week ago committed by GitHub
commit bf91426c45
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: block declaration tags and `{@const}` on async values read inside closures

@ -43,7 +43,8 @@ export function DeclarationTag(node, context) {
*/
export function mark_async_declaration(context, metadata, declarations) {
const has_await = metadata.expression.has_await;
const blockers = [...metadata.expression.dependencies]
// reads inside closures must block too, like they do in template expressions
const blockers = [...metadata.expression.references]
.map((dep) => dep.blocker)
.filter((b) => b !== null && b.object !== context.state.async_consts?.id);

@ -70,7 +70,7 @@ export function add_async_declaration(context, metadata, ids, assignments, kind
context.state.consts.push(kind === 'var' ? b.var(id.name) : b.let(id.name));
}
const blockers = [...metadata.expression.dependencies]
const blockers = [...metadata.expression.references]
.map((dep) => dep.blocker)
.filter((b) => b !== null && b.object !== context.state.async_consts?.id);

@ -66,7 +66,7 @@ export function add_async_declaration(context, metadata, ids, assignments, kind
context.state.init.push(kind === 'var' ? b.var(id.name) : b.let(id.name));
}
const blockers = [...metadata.expression.dependencies]
const blockers = [...metadata.expression.references]
.map((dep) => dep.blocker)
.filter((b) => b !== null && b.object !== context.state.async_consts?.id);

@ -0,0 +1,11 @@
import { tick } from 'svelte';
import { test } from '../../test';
// same fix as async-declaration-closure-read, via the shared helpers — an `{@const}`
// reading an async value inside a closure must block on it
export default test({
async test({ assert, target }) {
await tick();
assert.htmlEqual(target.innerHTML, '<p>true</p> <p>false</p>');
}
});

@ -0,0 +1,12 @@
<script>
async function getValue() {
return new Set(['a', 'b', 'c']);
}
const value = await getValue();
</script>
{#each [['a', 'b'], ['a', 'x']] as keys}
{@const all_present = keys.every((k) => value.has(k))}
<p>{all_present}</p>
{/each}

@ -0,0 +1,10 @@
import { tick } from 'svelte';
import { test } from '../../test';
// #18469 — a sync $derived in a nested snippet reading an async declaration through a closure must block on it
export default test({
async test({ assert, target }) {
await tick();
assert.htmlEqual(target.innerHTML, '<p>true</p> <p>false</p>');
}
});

@ -0,0 +1,17 @@
<script>
async function getValue() {
return new Set(['a', 'b', 'c']);
}
</script>
{#snippet outer()}
{const value = $derived(await getValue())}
{#snippet inner(keys)}
{const all_present = $derived(keys.every((k) => value.has(k)))}
<p>{all_present}</p>
{/snippet}
{@render inner(['a', 'b'])}
{@render inner(['a', 'x'])}
{/snippet}
{@render outer()}

@ -0,0 +1,17 @@
<script>
async function getValue() {
return new Set(['a', 'b', 'c']);
}
</script>
{#snippet outer()}
{const value = $derived(await getValue())}
{#snippet inner(keys)}
{const all_present = $derived(keys.every((k) => value.has(k)))}
<p>{all_present}</p>
{/snippet}
{@render inner(['a', 'b'])}
{@render inner(['a', 'x'])}
{/snippet}
{@render outer()}
Loading…
Cancel
Save