fix: improve unowned derived signal heuristics (#11029)

* fix: improve unowned derived signal heuristics

* spelling
pull/11018/head
Dominic Gannaway 1 year ago committed by GitHub
parent 2a784fce16
commit 1d52c1323b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

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

@ -171,6 +171,7 @@ export function check_dirtiness(reaction) {
if ((flags & MAYBE_DIRTY) !== 0) {
var dependencies = reaction.deps;
var is_unowned = (flags & UNOWNED) !== 0;
if (dependencies !== null) {
var length = dependencies.length;
@ -191,7 +192,6 @@ export function check_dirtiness(reaction) {
// if our dependency write version is higher. If it is then we can assume
// that state has changed to a newer version and thus this unowned signal
// is also dirty.
var is_unowned = (flags & UNOWNED) !== 0;
var version = dependency.version;
if (is_unowned && version > /** @type {import('#client').Derived} */ (reaction).version) {
@ -201,7 +201,10 @@ export function check_dirtiness(reaction) {
}
}
set_signal_status(reaction, CLEAN);
// Unowned signals are always maybe dirty, as we instead check their dependency versions.
if (!is_unowned) {
set_signal_status(reaction, CLEAN);
}
}
return false;

@ -0,0 +1,17 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target }) {
let [btn1] = target.querySelectorAll('button');
flushSync(() => {
btn1.click();
});
assert.htmlEqual(
target.innerHTML,
`<button>update</button><div>2</div><div>2</div><div>2</div><div>2</div>`
);
}
});

@ -0,0 +1,33 @@
<script>
let thing = $state();
function update() {
let data = $state({ name: 1, position: 1 });
let position = $derived(data.position);
let name = $derived(data.name);
thing = {
get data() { return data },
get position() { return position },
get name() { return name },
}
thing.position;
data = { name: 2, position: 2 };
}
</script>
<button onclick={update}>update</button>
<div>
{thing?.data?.name}
</div>
<div>
{thing?.name}
</div>
<div>
{thing?.data?.position}
</div>
<div>
{thing?.position}
</div>
Loading…
Cancel
Save