From de315d84eb4048bd9948a41c82614043a7cdf7a4 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 29 Apr 2024 21:26:56 +0200 Subject: [PATCH] fix: ensure reactions are kept dirty when marking them again (#11364) previously a reaction could be marked as DIRTY and subsequently as MAYBE_DIRTY before running, resulting in false negatives. Ensure that DIRTY flag can never be lowered to MAYBE_DIRTY fixes #11363 --- .changeset/empty-geckos-pretend.md | 5 +++++ packages/svelte/src/internal/client/runtime.js | 8 ++++---- .../derived-write-read-write-read/_config.js | 8 ++++++++ .../derived-write-read-write-read/main.svelte | 13 +++++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 .changeset/empty-geckos-pretend.md create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-write-read-write-read/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-write-read-write-read/main.svelte diff --git a/.changeset/empty-geckos-pretend.md b/.changeset/empty-geckos-pretend.md new file mode 100644 index 0000000000..defe2fb419 --- /dev/null +++ b/.changeset/empty-geckos-pretend.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: ensure reactions are kept dirty when marking them again diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 9e268a3966..4364a52199 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -780,7 +780,7 @@ export function invalidate_inner_signals(fn) { /** * @param {import('#client').Value} signal - * @param {number} to_status + * @param {number} to_status should be DIRTY or MAYBE_DIRTY * @param {boolean} force_schedule * @returns {void} */ @@ -793,15 +793,15 @@ export function mark_reactions(signal, to_status, force_schedule) { for (var i = 0; i < length; i++) { var reaction = reactions[i]; + var flags = reaction.f; - // We skip any effects that are already dirty (but not unowned). Additionally, we also + // We skip any effects that are already dirty. Additionally, we also // skip if the reaction is the same as the current effect (except if we're not in runes or we // are in force schedule mode). - if ((!force_schedule || !runes) && reaction === current_effect) { + if ((flags & DIRTY) !== 0 || ((!force_schedule || !runes) && reaction === current_effect)) { continue; } - var flags = reaction.f; set_signal_status(reaction, to_status); // If the signal is not clean, then skip over it – with the exception of unowned signals that diff --git a/packages/svelte/tests/runtime-runes/samples/derived-write-read-write-read/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-write-read-write-read/_config.js new file mode 100644 index 0000000000..fe8d5b732f --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-write-read-write-read/_config.js @@ -0,0 +1,8 @@ +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + await target.querySelector('button')?.click(); + assert.htmlEqual(target.innerHTML, ``); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/derived-write-read-write-read/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-write-read-write-read/main.svelte new file mode 100644 index 0000000000..1e449198be --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-write-read-write-read/main.svelte @@ -0,0 +1,13 @@ + + + \ No newline at end of file