diff --git a/.changeset/tasty-carrots-tie.md b/.changeset/tasty-carrots-tie.md new file mode 100644 index 0000000000..5d6cb8025d --- /dev/null +++ b/.changeset/tasty-carrots-tie.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: properly invoke `iterator.return()` during reactivity loss check diff --git a/packages/svelte/src/internal/client/reactivity/async.js b/packages/svelte/src/internal/client/reactivity/async.js index d713385c75..7b0b108e4c 100644 --- a/packages/svelte/src/internal/client/reactivity/async.js +++ b/packages/svelte/src/internal/client/reactivity/async.js @@ -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); } diff --git a/packages/svelte/tests/runtime-runes/samples/async-reactivity-loss-for-await-break-return/_config.js b/packages/svelte/tests/runtime-runes/samples/async-reactivity-loss-for-await-break-return/_config.js new file mode 100644 index 0000000000..3429380800 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-reactivity-loss-for-await-break-return/_config.js @@ -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: '

pending

', + async test({ assert, target, warnings }) { + await tick(); + + assert.htmlEqual(target.innerHTML, '

number -> number -> number -> return -> ended

'); + + 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`' + } + ]); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-reactivity-loss-for-await-break-return/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-reactivity-loss-for-await-break-return/main.svelte new file mode 100644 index 0000000000..05ad7a6ee5 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-reactivity-loss-for-await-break-return/main.svelte @@ -0,0 +1,41 @@ + + + +

{await get_result()}

+ + {#snippet pending()} +

pending

+ {/snippet} +