pull/17966/merge
Simon H 1 day ago committed by GitHub
commit e56718a931
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: properly invoke `iterator.return()` during reactivity loss check

@ -209,8 +209,8 @@ export async function* for_await_track_reactivity_loss(iterable) {
yield value;
}
} finally {
// If the iterator had a normal completion and `return` is defined on the iterator, call it and return the value
if (normal_completion && iterator.return !== undefined) {
// If the iterator had an abrupt completion and `return` is defined on the iterator, call it and return the value
if (!normal_completion && iterator.return !== undefined) {
// eslint-disable-next-line no-unsafe-finally
return /** @type {TReturn} */ ((await track_reactivity_loss(iterator.return()))().value);
}

@ -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 -> number -> return -> ended</h1>');
assert.deepEqual(normalise_trace_logs(warnings), [
{
log: 'Detected reactivity loss when reading `values.length`. This happens when state is read in an async function after an earlier `await`'
}
]);
}
});

@ -0,0 +1,41 @@
<script>
let values = $state([0, 1, 2]);
async function get_result() {
const logs = [];
const iterator = {
index: 0,
async next() {
if (this.index >= values.length) return { done: true };
return { done: false, value: values[this.index++] };
},
async return() {
logs.push('return');
return { done: true };
},
[Symbol.asyncIterator]() {
return this;
}
};
for await (const value of iterator) {
logs.push('number');
// read reactive state after async iterator await
if (values.length === 3 && value === 2) {
break;
}
}
logs.push('ended');
return logs.join(' -> ');
}
</script>
<svelte:boundary>
<h1>{await get_result()}</h1>
{#snippet pending()}
<p>pending</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save