Fix unowned bug 2 (#11077)

* fix: improve handled of unowned derived signals

* fix: improve handled of unowned derived signals

* lint
pull/11072/head
Dominic Gannaway 9 months ago committed by GitHub
parent 071d6314d9
commit 452749494e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

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

@ -194,9 +194,21 @@ export function check_dirtiness(reaction) {
// is also dirty.
var version = dependency.version;
if (is_unowned && version > /** @type {import('#client').Derived} */ (reaction).version) {
/** @type {import('#client').Derived} */ (reaction).version = version;
return true;
if (is_unowned) {
if (version > /** @type {import('#client').Derived} */ (reaction).version) {
/** @type {import('#client').Derived} */ (reaction).version = version;
return true;
} else if (!current_skip_reaction && !dependency?.reactions?.includes(reaction)) {
// If we are working with an unowned signal as part of an effect (due to !current_skip_reaction)
// and the version hasn't changed, we still need to check that this reaction
// if linked to the dependency source otherwise future updates will not be caught.
var reactions = dependency.reactions;
if (reactions === null) {
dependency.reactions = [reaction];
} else {
reactions.push(reaction);
}
}
}
}
}

@ -0,0 +1,12 @@
import { test } from '../../test';
export default test({
async test({ assert, target }) {
// The test has a bunch of queueMicrotasks
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
assert.htmlEqual(target.innerHTML, `<div>Zeeba Neighba</div>`);
}
});

@ -0,0 +1,34 @@
<script context="module">
export class Thing {
data = $state();
subscribe() {
queueMicrotask(() => {
this.data = {
name: `Zeeba Neighba`,
};
});
}
name = $derived(this.data?.name);
}
export class Things {
thing = $state();
subscribe() {
queueMicrotask(() => {
this.thing = new Thing();
this.thing.subscribe();
this.thing.name;
});
}
}
</script>
<script>
let model = new Things();
$effect(() => model.subscribe());
</script>
<div>{model.thing?.name}</div>
Loading…
Cancel
Save