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