From 7bef5963bd3c5eb05f7722e09b4e6b806c2da337 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Thu, 30 Jan 2025 18:17:27 +0000 Subject: [PATCH] fix: ensure reactions are correctly attached for unowned deriveds (#15158) * fix: ensure reactions are correctly attached for unowned deriveds * tune --- .changeset/loud-cars-scream.md | 5 +++++ packages/svelte/src/internal/client/runtime.js | 13 +++++++++---- .../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, 51 insertions(+), 4 deletions(-) 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..a572e27bf467 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; } } @@ -952,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; } } 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 @@ + + + + + +