mirror of https://github.com/sveltejs/svelte
commit
c92989ad10
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: rethrow error of failed iterable after calling `return()`
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: wrap `Promise.all` in `save` during SSR
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
import { normalise_trace_logs } from '../../../helpers.js';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
compileOptions: {
|
||||||
|
dev: true
|
||||||
|
},
|
||||||
|
html: '<p>pending</p>',
|
||||||
|
async test({ assert, target, warnings }) {
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
'<h1>number -> number -> number -> return -> body failed -> ended</h1>'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.deepEqual(normalise_trace_logs(warnings), [
|
||||||
|
{
|
||||||
|
log: 'Detected reactivity loss when reading `values[1]`. This happens when state is read in an async function after an earlier `await`'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
<script>
|
||||||
|
let values = $state([0, 1, 2]);
|
||||||
|
|
||||||
|
async function get_result() {
|
||||||
|
const logs = [];
|
||||||
|
|
||||||
|
const iterator = {
|
||||||
|
index: 0,
|
||||||
|
async next() {
|
||||||
|
if (this.index > 2) { done: true }
|
||||||
|
return { done: false, value: values[this.index++] };
|
||||||
|
},
|
||||||
|
async return() {
|
||||||
|
logs.push('return');
|
||||||
|
},
|
||||||
|
[Symbol.asyncIterator]() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
for await (const value of iterator) {
|
||||||
|
logs.push('number');
|
||||||
|
// Read reactive state after async iterator await.
|
||||||
|
if (values.length === 3 && value === 2) {
|
||||||
|
throw new Error('body failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logs.push('done');
|
||||||
|
} catch (error) {
|
||||||
|
logs.push(error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
logs.push('ended');
|
||||||
|
return logs.join(' -> ');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:boundary>
|
||||||
|
<h1>{await get_result()}</h1>
|
||||||
|
|
||||||
|
{#snippet pending()}
|
||||||
|
<p>pending</p>
|
||||||
|
{/snippet}
|
||||||
|
</svelte:boundary>
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
import { normalise_trace_logs } from '../../../helpers.js';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
compileOptions: {
|
||||||
|
dev: true
|
||||||
|
},
|
||||||
|
html: '<p>pending</p>',
|
||||||
|
async test({ assert, target, warnings }) {
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, '<h1>number -> number -> next failed -> ended</h1>');
|
||||||
|
|
||||||
|
assert.deepEqual(normalise_trace_logs(warnings), [
|
||||||
|
{
|
||||||
|
log: 'Detected reactivity loss when reading `values[1]`. This happens when state is read in an async function after an earlier `await`'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
<script>
|
||||||
|
let values = $state([0, 1, 2]);
|
||||||
|
|
||||||
|
async function get_result() {
|
||||||
|
const logs = [];
|
||||||
|
|
||||||
|
const iterator = {
|
||||||
|
index: 0,
|
||||||
|
async next() {
|
||||||
|
if (this.index > 1) throw new Error('next failed');
|
||||||
|
return { done: false, value: values[this.index++] };
|
||||||
|
},
|
||||||
|
async return() {
|
||||||
|
logs.push('return');
|
||||||
|
},
|
||||||
|
[Symbol.asyncIterator]() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
for await (const value of iterator) {
|
||||||
|
logs.push('number');
|
||||||
|
// Read reactive state after async iterator await.
|
||||||
|
values.length === value;
|
||||||
|
}
|
||||||
|
logs.push('done');
|
||||||
|
} catch (error) {
|
||||||
|
logs.push(error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
logs.push('ended');
|
||||||
|
return logs.join(' -> ');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:boundary>
|
||||||
|
<h1>{await get_result()}</h1>
|
||||||
|
|
||||||
|
{#snippet pending()}
|
||||||
|
<p>pending</p>
|
||||||
|
{/snippet}
|
||||||
|
</svelte:boundary>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
mode: ['async'],
|
||||||
|
compileOptions: {
|
||||||
|
dev: true
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<!--[--><img alt="test" src=""/><!--]-->
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<!--1410iyz--><!----><title>Async multiple attributes</title>
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
<script>
|
||||||
|
const user = $derived(Promise.resolve({
|
||||||
|
name: 'test',
|
||||||
|
image: '',
|
||||||
|
}))
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Async multiple attributes</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<img
|
||||||
|
alt={(await user).name}
|
||||||
|
src={(await user).image}
|
||||||
|
/>
|
||||||
Loading…
Reference in new issue