Skip to content

Commit 4527494

Browse files
authored
Fix unowned bug 2 (#11077)
* fix: improve handled of unowned derived signals * fix: improve handled of unowned derived signals * lint
1 parent 071d631 commit 4527494

File tree

4 files changed

+66
-3
lines changed

4 files changed

+66
-3
lines changed

.changeset/rich-garlics-laugh.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 handled of unowned derived signals

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,21 @@ export function check_dirtiness(reaction) {
194194
// is also dirty.
195195
var version = dependency.version;
196196

197-
if (is_unowned && version > /** @type {import('#client').Derived} */ (reaction).version) {
198-
/** @type {import('#client').Derived} */ (reaction).version = version;
199-
return true;
197+
if (is_unowned) {
198+
if (version > /** @type {import('#client').Derived} */ (reaction).version) {
199+
/** @type {import('#client').Derived} */ (reaction).version = version;
200+
return true;
201+
} else if (!current_skip_reaction && !dependency?.reactions?.includes(reaction)) {
202+
// If we are working with an unowned signal as part of an effect (due to !current_skip_reaction)
203+
// and the version hasn't changed, we still need to check that this reaction
204+
// if linked to the dependency source – otherwise future updates will not be caught.
205+
var reactions = dependency.reactions;
206+
if (reactions === null) {
207+
dependency.reactions = [reaction];
208+
} else {
209+
reactions.push(reaction);
210+
}
211+
}
200212
}
201213
}
202214
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
async test({ assert, target }) {
5+
// The test has a bunch of queueMicrotasks
6+
await Promise.resolve();
7+
await Promise.resolve();
8+
await Promise.resolve();
9+
10+
assert.htmlEqual(target.innerHTML, `<div>Zeeba Neighba</div>`);
11+
}
12+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script context="module">
2+
export class Thing {
3+
data = $state();
4+
5+
subscribe() {
6+
queueMicrotask(() => {
7+
this.data = {
8+
name: `Zeeba Neighba`,
9+
};
10+
});
11+
}
12+
13+
name = $derived(this.data?.name);
14+
}
15+
16+
export class Things {
17+
thing = $state();
18+
19+
subscribe() {
20+
queueMicrotask(() => {
21+
this.thing = new Thing();
22+
this.thing.subscribe();
23+
this.thing.name;
24+
});
25+
}
26+
}
27+
</script>
28+
29+
<script>
30+
let model = new Things();
31+
$effect(() => model.subscribe());
32+
</script>
33+
34+
<div>{model.thing?.name}</div>

0 commit comments

Comments
 (0)