fix: improve behaviour of unowned derived signals (#11521)

pull/11518/head
Dominic Gannaway 8 months ago committed by GitHub
parent 70419daf5f
commit 30caaef2e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: improve behaviour of unowned derived signals

@ -85,7 +85,7 @@ function destroy_derived_children(signal) {
/** /**
* @param {import('#client').Derived} derived * @param {import('#client').Derived} derived
* @param {boolean} force_schedule * @param {boolean} force_schedule
* @returns {void} * @returns {boolean}
*/ */
export function update_derived(derived, force_schedule) { export function update_derived(derived, force_schedule) {
var previous_updating_derived = updating_derived; var previous_updating_derived = updating_derived;
@ -101,7 +101,9 @@ export function update_derived(derived, force_schedule) {
set_signal_status(derived, status); set_signal_status(derived, status);
if (!derived.equals(value)) { var is_equal = derived.equals(value);
if (!is_equal) {
derived.v = value; derived.v = value;
mark_reactions(derived, DIRTY, force_schedule); mark_reactions(derived, DIRTY, force_schedule);
@ -109,6 +111,8 @@ export function update_derived(derived, force_schedule) {
for (var fn of /** @type {import('#client').DerivedDebug} */ (derived).inspect) fn(); for (var fn of /** @type {import('#client').DerivedDebug} */ (derived).inspect) fn();
} }
} }
return is_equal;
} }
/** /**

@ -191,12 +191,13 @@ export function check_dirtiness(reaction) {
if (dependencies !== null) { if (dependencies !== null) {
var length = dependencies.length; var length = dependencies.length;
var is_equal;
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
var dependency = dependencies[i]; var dependency = dependencies[i];
if (!is_dirty && 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); is_equal = update_derived(/** @type {import('#client').Derived} **/ (dependency), true);
} }
if (is_unowned) { if (is_unowned) {
@ -208,7 +209,7 @@ export function check_dirtiness(reaction) {
if (version > /** @type {import('#client').Derived} */ (reaction).version) { if (version > /** @type {import('#client').Derived} */ (reaction).version) {
/** @type {import('#client').Derived} */ (reaction).version = version; /** @type {import('#client').Derived} */ (reaction).version = version;
return true; return !is_equal;
} }
if (!current_skip_reaction && !dependency?.reactions?.includes(reaction)) { if (!current_skip_reaction && !dependency?.reactions?.includes(reaction)) {

@ -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 C', 'computing B', 'a', 'foo', 'computing B', 'aaa', 'foo']);
}
});

@ -0,0 +1,19 @@
<script>
function run(){
let a = $state('a');
let b = $derived.by(() => {
console.log('computing B', a);
return 'foo';
});
let c = $derived.by(() => {
console.log('computing C');
return b;
});
console.log(c);
a = "aaa";
console.log(c);
}
</script>
<button onclick={run}>RUN THE THING</button>
Loading…
Cancel
Save