From 0f4f3d7df04cf749e3fe35fc9b625fdc7b61dc9c Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Wed, 1 May 2024 15:07:04 +0100 Subject: [PATCH] fix: improve unowned derived signal behaviour (#11408) --- .changeset/wise-ties-clap.md | 5 +++++ .../svelte/src/internal/client/runtime.js | 13 +++++++----- .../samples/derived-unowned-6/_config.js | 14 +++++++++++++ .../samples/derived-unowned-6/main.svelte | 21 +++++++++++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 .changeset/wise-ties-clap.md create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-unowned-6/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/derived-unowned-6/main.svelte diff --git a/.changeset/wise-ties-clap.md b/.changeset/wise-ties-clap.md new file mode 100644 index 0000000000..8a01e62f1e --- /dev/null +++ b/.changeset/wise-ties-clap.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: improve unowned derived signal behaviour diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index ac07ec1922..7b581cde29 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -160,14 +160,17 @@ export function batch_inspect(target, prop, receiver) { */ export function check_dirtiness(reaction) { var flags = reaction.f; + var is_dirty = (flags & DIRTY) !== 0; + var is_unowned = (flags & UNOWNED) !== 0; - if ((flags & DIRTY) !== 0) { + // If we are unowned, we still need to ensure that we update our version to that + // of our dependencies. + if (is_dirty && !is_unowned) { return true; } - if ((flags & MAYBE_DIRTY) !== 0) { + if ((flags & MAYBE_DIRTY) !== 0 || (is_dirty && is_unowned)) { var dependencies = reaction.deps; - var is_unowned = (flags & UNOWNED) !== 0; if (dependencies !== null) { var length = dependencies.length; @@ -175,7 +178,7 @@ export function check_dirtiness(reaction) { for (var i = 0; i < length; i++) { var dependency = dependencies[i]; - if (check_dirtiness(/** @type {import('#client').Derived} */ (dependency))) { + 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` @@ -217,7 +220,7 @@ export function check_dirtiness(reaction) { } } - return false; + return is_dirty; } /** diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-6/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-unowned-6/_config.js new file mode 100644 index 0000000000..d959b4c679 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-6/_config.js @@ -0,0 +1,14 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target, logs }) { + let [btn1] = target.querySelectorAll('button'); + + flushSync(() => { + btn1.click(); + }); + + assert.deepEqual(logs, ['computing', 'a', 'a', 'computing', 'bb', 'bb']); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-6/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-unowned-6/main.svelte new file mode 100644 index 0000000000..2355e227ae --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-6/main.svelte @@ -0,0 +1,21 @@ + + +