make validate_each_keys async-aware

pull/15844/head
Simon Holthausen 3 months ago
parent 951d8e6e69
commit fdd009b60d

@ -312,14 +312,7 @@ export function EachBlock(node, context) {
declarations.push(b.let(node.index, index)); declarations.push(b.let(node.index, index));
} }
if (dev && node.metadata.keyed) {
context.state.init.push(
b.stmt(b.call('$.validate_each_keys', b.thunk(collection), key_function))
);
}
const { has_await } = node.metadata.expression; const { has_await } = node.metadata.expression;
const thunk = b.thunk(collection, has_await); const thunk = b.thunk(collection, has_await);
const render_args = [b.id('$$anchor'), item]; const render_args = [b.id('$$anchor'), item];
@ -342,20 +335,34 @@ export function EachBlock(node, context) {
} }
if (has_await) { if (has_await) {
const statements = [b.stmt(b.call('$.each', ...args))];
if (dev && node.metadata.keyed) {
statements.unshift(
b.stmt(
b.call(
'$.validate_each_keys',
b.thunk(b.call('$.get', b.id('$$collection'))),
key_function
)
)
);
}
context.state.init.push( context.state.init.push(
b.stmt( b.stmt(
b.call( b.call(
'$.async', '$.async',
context.state.node, context.state.node,
b.array([thunk]), b.array([thunk]),
b.arrow( b.arrow([context.state.node, b.id('$$collection')], b.block(statements))
[context.state.node, b.id('$$collection')],
b.block([b.stmt(b.call('$.each', ...args))])
)
) )
) )
); );
} else { } else {
if (dev && node.metadata.keyed) {
context.state.init.push(
b.stmt(b.call('$.validate_each_keys', b.thunk(collection), key_function))
);
}
context.state.init.push(b.stmt(b.call('$.each', ...args))); context.state.init.push(b.stmt(b.call('$.each', ...args)));
} }
} }

@ -0,0 +1,44 @@
import { tick } from 'svelte';
import { deferred } from '../../../../src/internal/shared/utils.js';
import { test } from '../../test';
/** @type {ReturnType<typeof deferred>} */
let d;
export default test({
compileOptions: {
dev: true
},
html: `<p>pending</p>`,
get props() {
d = deferred();
return {
promise: d.promise
};
},
async test({ assert, target, component }) {
d.resolve(['a', 'b', 'c']);
await tick();
assert.htmlEqual(target.innerHTML, '<p>a</p><p>b</p><p>c</p>');
d = deferred();
component.promise = d.promise;
await tick();
assert.htmlEqual(target.innerHTML, '<p>a</p><p>b</p><p>c</p>');
d.resolve(['d', 'e', 'f', 'g']);
await tick();
assert.htmlEqual(target.innerHTML, '<p>d</p><p>e</p><p>f</p><p>g</p>');
d = deferred();
component.promise = d.promise;
d.resolve(['d', 'e', 'f', 'd']);
await tick();
assert.fail('should not allow duplicate keys');
},
runtime_error: 'each_key_duplicate'
});

@ -0,0 +1,13 @@
<script>
let { promise } = $props();
</script>
<svelte:boundary>
{#each await promise as item (item)}
<p>{item}</p>
{/each}
{#snippet pending()}
<p>pending</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save