Skip to content

Commit 1d52c13

Browse files
authored
fix: improve unowned derived signal heuristics (#11029)
* fix: improve unowned derived signal heuristics * spelling
1 parent 2a784fc commit 1d52c13

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

.changeset/big-moons-occur.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 unowned derived signal heuristics

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ export function check_dirtiness(reaction) {
171171

172172
if ((flags & MAYBE_DIRTY) !== 0) {
173173
var dependencies = reaction.deps;
174+
var is_unowned = (flags & UNOWNED) !== 0;
174175

175176
if (dependencies !== null) {
176177
var length = dependencies.length;
@@ -191,7 +192,6 @@ export function check_dirtiness(reaction) {
191192
// if our dependency write version is higher. If it is then we can assume
192193
// that state has changed to a newer version and thus this unowned signal
193194
// is also dirty.
194-
var is_unowned = (flags & UNOWNED) !== 0;
195195
var version = dependency.version;
196196

197197
if (is_unowned && version > /** @type {import('#client').Derived} */ (reaction).version) {
@@ -201,7 +201,10 @@ export function check_dirtiness(reaction) {
201201
}
202202
}
203203

204-
set_signal_status(reaction, CLEAN);
204+
// Unowned signals are always maybe dirty, as we instead check their dependency versions.
205+
if (!is_unowned) {
206+
set_signal_status(reaction, CLEAN);
207+
}
205208
}
206209

207210
return false;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, target }) {
6+
let [btn1] = target.querySelectorAll('button');
7+
8+
flushSync(() => {
9+
btn1.click();
10+
});
11+
12+
assert.htmlEqual(
13+
target.innerHTML,
14+
`<button>update</button><div>2</div><div>2</div><div>2</div><div>2</div>`
15+
);
16+
}
17+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<script>
2+
let thing = $state();
3+
4+
function update() {
5+
let data = $state({ name: 1, position: 1 });
6+
let position = $derived(data.position);
7+
let name = $derived(data.name);
8+
9+
thing = {
10+
get data() { return data },
11+
get position() { return position },
12+
get name() { return name },
13+
}
14+
15+
thing.position;
16+
data = { name: 2, position: 2 };
17+
}
18+
</script>
19+
20+
<button onclick={update}>update</button>
21+
22+
<div>
23+
{thing?.data?.name}
24+
</div>
25+
<div>
26+
{thing?.name}
27+
</div>
28+
<div>
29+
{thing?.data?.position}
30+
</div>
31+
<div>
32+
{thing?.position}
33+
</div>

0 commit comments

Comments
 (0)