From fc43cffd8dfbfbd86438b268e70e2d855b0a5201 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 7 May 2024 10:29:40 +0200 Subject: [PATCH] fix: ensure derived is detected as dirty correctly Deriveds where under certain conditions not detected as dirty correctly. The reason is that a transitive check_dirtiness call could update the flag of a derived, even if the condition doesn't ulimately result to true. That's why the check for "is now dirty" needs to be moved out of the inner if block. Fixes #11481 This may also fix a yet undetected overfiring bug in the "is unowned" case because the previous inner "is now dirty?" check didn't take unowned into account. --- .changeset/shiny-melons-love.md | 5 +++++ packages/svelte/src/internal/client/runtime.js | 8 +++----- .../runtime-runes/samples/derived-cascade/_config.js | 12 ++++++++++++ .../samples/derived-cascade/main.svelte | 12 ++++++++++++ 4 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 .changeset/shiny-melons-love.md create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-cascade/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-cascade/main.svelte diff --git a/.changeset/shiny-melons-love.md b/.changeset/shiny-melons-love.md new file mode 100644 index 000000000000..5633aff875c5 --- /dev/null +++ b/.changeset/shiny-melons-love.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: ensure derived is detected as dirty correctly diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index cb5bb185c059..be35678c1167 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -200,11 +200,6 @@ export function check_dirtiness(reaction) { if (!is_dirty && check_dirtiness(/** @type {import('#client').Derived} */ (dependency))) { update_derived(/** @type {import('#client').Derived} **/ (dependency), true); - - // `signal` might now be dirty, as a result of calling `update_derived` - if ((reaction.f & DIRTY) !== 0) { - return true; - } } if (is_unowned) { @@ -230,6 +225,9 @@ export function check_dirtiness(reaction) { reactions.push(reaction); } } + } else if ((reaction.f & DIRTY) !== 0) { + // `signal` might now be dirty, as a result of calling `check_dirtiness` and/or `update_derived` + return true; } } } diff --git a/packages/svelte/tests/runtime-runes/samples/derived-cascade/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-cascade/_config.js new file mode 100644 index 000000000000..ddadfb64f7b3 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-cascade/_config.js @@ -0,0 +1,12 @@ +import { test } from '../../test'; + +export default test({ + html: ``, + + async test({ assert, target }) { + const btn = target.querySelector('button'); + await btn?.click(); + + assert.htmlEqual(target.innerHTML, ``); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/derived-cascade/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-cascade/main.svelte new file mode 100644 index 000000000000..c0d45c85322d --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-cascade/main.svelte @@ -0,0 +1,12 @@ + + +