Skip to content

Commit 30caaef

Browse files
authored
fix: improve behaviour of unowned derived signals (#11521)
1 parent 70419da commit 30caaef

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

.changeset/fluffy-ravens-juggle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
fix: improve behaviour of unowned derived signals

packages/svelte/src/internal/client/reactivity/deriveds.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function destroy_derived_children(signal) {
8585
/**
8686
* @param {import('#client').Derived} derived
8787
* @param {boolean} force_schedule
88-
* @returns {void}
88+
* @returns {boolean}
8989
*/
9090
export function update_derived(derived, force_schedule) {
9191
var previous_updating_derived = updating_derived;
@@ -101,14 +101,18 @@ export function update_derived(derived, force_schedule) {
101101

102102
set_signal_status(derived, status);
103103

104-
if (!derived.equals(value)) {
104+
var is_equal = derived.equals(value);
105+
106+
if (!is_equal) {
105107
derived.v = value;
106108
mark_reactions(derived, DIRTY, force_schedule);
107109

108110
if (DEV && force_schedule) {
109111
for (var fn of /** @type {import('#client').DerivedDebug} */ (derived).inspect) fn();
110112
}
111113
}
114+
115+
return is_equal;
112116
}
113117

114118
/**

packages/svelte/src/internal/client/runtime.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,13 @@ export function check_dirtiness(reaction) {
191191

192192
if (dependencies !== null) {
193193
var length = dependencies.length;
194+
var is_equal;
194195

195196
for (var i = 0; i < length; i++) {
196197
var dependency = dependencies[i];
197198

198199
if (!is_dirty && check_dirtiness(/** @type {import('#client').Derived} */ (dependency))) {
199-
update_derived(/** @type {import('#client').Derived} **/ (dependency), true);
200+
is_equal = update_derived(/** @type {import('#client').Derived} **/ (dependency), true);
200201
}
201202

202203
if (is_unowned) {
@@ -208,7 +209,7 @@ export function check_dirtiness(reaction) {
208209

209210
if (version > /** @type {import('#client').Derived} */ (reaction).version) {
210211
/** @type {import('#client').Derived} */ (reaction).version = version;
211-
return true;
212+
return !is_equal;
212213
}
213214

214215
if (!current_skip_reaction && !dependency?.reactions?.includes(reaction)) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, target, logs }) {
6+
let [btn1] = target.querySelectorAll('button');
7+
8+
flushSync(() => {
9+
btn1.click();
10+
});
11+
12+
assert.deepEqual(logs, ['computing C', 'computing B', 'a', 'foo', 'computing B', 'aaa', 'foo']);
13+
}
14+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<script>
2+
function run(){
3+
let a = $state('a');
4+
let b = $derived.by(() => {
5+
console.log('computing B', a);
6+
return 'foo';
7+
});
8+
let c = $derived.by(() => {
9+
console.log('computing C');
10+
return b;
11+
});
12+
13+
console.log(c);
14+
a = "aaa";
15+
console.log(c);
16+
}
17+
</script>
18+
19+
<button onclick={run}>RUN THE THING</button>

0 commit comments

Comments
 (0)