fix: improve unowned derived signal behaviour (#11408)

pull/11421/head
Dominic Gannaway 8 months ago committed by GitHub
parent 4d051962f3
commit 0f4f3d7df0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

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

@ -160,14 +160,17 @@ export function batch_inspect(target, prop, receiver) {
*/ */
export function check_dirtiness(reaction) { export function check_dirtiness(reaction) {
var flags = reaction.f; 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; return true;
} }
if ((flags & MAYBE_DIRTY) !== 0) { if ((flags & MAYBE_DIRTY) !== 0 || (is_dirty && is_unowned)) {
var dependencies = reaction.deps; var dependencies = reaction.deps;
var is_unowned = (flags & UNOWNED) !== 0;
if (dependencies !== null) { if (dependencies !== null) {
var length = dependencies.length; var length = dependencies.length;
@ -175,7 +178,7 @@ export function check_dirtiness(reaction) {
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
var dependency = dependencies[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); update_derived(/** @type {import('#client').Derived} **/ (dependency), true);
// `signal` might now be dirty, as a result of calling `update_derived` // `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;
} }
/** /**

@ -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']);
}
});

@ -0,0 +1,21 @@
<script>
function run(){
let cond = $state(true);
let a = $state("a");
let b = $state("b");
let c = $derived.by(() => {
console.log('computing')
return cond ? a : b
});
console.log(c);
b = "bb";
console.log(c)
cond = false;
console.log(c)
a = "aaa";
console.log(c)
}
</script>
<button onclick={run}>RUN THE THING</button>
Loading…
Cancel
Save