From 3117bb66d925f964ebf6f90f75c55fbc8f60cabc Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Thu, 30 Jan 2025 16:52:13 +0000 Subject: [PATCH 1/2] fix: ensure reactions are correctly attached for unowned deriveds --- .changeset/loud-cars-scream.md | 5 +++++ packages/svelte/src/internal/client/runtime.js | 7 +++++++ .../samples/derived-unowned-11/Child.svelte | 5 +++++ .../samples/derived-unowned-11/Child2.svelte | 5 +++++ .../samples/derived-unowned-11/_config.js | 16 ++++++++++++++++ .../samples/derived-unowned-11/main.svelte | 11 +++++++++++ 6 files changed, 49 insertions(+) create mode 100644 .changeset/loud-cars-scream.md create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-unowned-11/Child.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-unowned-11/Child2.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-unowned-11/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-unowned-11/main.svelte diff --git a/.changeset/loud-cars-scream.md b/.changeset/loud-cars-scream.md new file mode 100644 index 000000000000..2b61bc44530a --- /dev/null +++ b/.changeset/loud-cars-scream.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure reactions are correctly attached for unowned deriveds diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index bf9d17fa2303..fb75eee83f0c 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -802,12 +802,19 @@ function process_effects(effect, collected_effects) { if (is_branch) { current_effect.f ^= CLEAN; } else { + // Ensure we set the effect to be the active reaction + // to ensure that unowned deriveds are correctly tracked + // because we're flushing the current effect + var previous_active_reaction = active_reaction; try { + active_reaction = current_effect; if (check_dirtiness(current_effect)) { update_effect(current_effect); } } catch (error) { handle_error(error, current_effect, null, current_effect.ctx); + } finally { + active_reaction = previous_active_reaction; } } diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/Child.svelte b/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/Child.svelte new file mode 100644 index 000000000000..cd215304a326 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/Child.svelte @@ -0,0 +1,5 @@ + + + diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/Child2.svelte b/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/Child2.svelte new file mode 100644 index 000000000000..a1d9f93bec71 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/Child2.svelte @@ -0,0 +1,5 @@ + + +{disabled} diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/_config.js new file mode 100644 index 000000000000..9948f9196683 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/_config.js @@ -0,0 +1,16 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + let [btn1, btn2] = target.querySelectorAll('button'); + + btn1?.click(); + flushSync(); + + btn2?.click(); + flushSync(); + + assert.htmlEqual(target.innerHTML, `\nfalse`); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/main.svelte new file mode 100644 index 000000000000..0219acdf7f99 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-11/main.svelte @@ -0,0 +1,11 @@ + + + + + + From f04f22bdb11aefa2facc762cddc64a5accedcc72 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Thu, 30 Jan 2025 17:45:54 +0000 Subject: [PATCH 2/2] tune --- packages/svelte/src/internal/client/runtime.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index fb75eee83f0c..a572e27bf467 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -959,13 +959,11 @@ export function get(signal) { var derived = /** @type {Derived} */ (signal); var parent = derived.parent; - if (parent !== null) { + if (parent !== null && (parent.f & UNOWNED) === 0) { // If the derived is owned by another derived then mark it as unowned // as the derived value might have been referenced in a different context // since and thus its parent might not be its true owner anymore - if ((parent.f & UNOWNED) === 0) { - derived.f ^= UNOWNED; - } + derived.f ^= UNOWNED; } }