fix: improve handling of unowned derived signals (#10842)

pull/10846/head
Dominic Gannaway 9 months ago committed by GitHub
parent 1fc41730a1
commit 117082b039
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

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

@ -41,7 +41,7 @@ export function derived(fn) {
/** @type {import('#client').DerivedDebug} */ (signal).inspect = new Set(); /** @type {import('#client').DerivedDebug} */ (signal).inspect = new Set();
} }
if (current_reaction !== null) { if (current_reaction !== null && (current_reaction.f & DERIVED) !== 0) {
if (current_reaction.deriveds === null) { if (current_reaction.deriveds === null) {
current_reaction.deriveds = [signal]; current_reaction.deriveds = [signal];
} else { } else {

@ -0,0 +1,30 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target }) {
let [btn1, btn2] = target.querySelectorAll('button');
flushSync(() => {
btn1.click();
});
flushSync(() => {
btn2.click();
});
assert.htmlEqual(
target.innerHTML,
`<button>Activate</button><button>Toggle</button>\nneighba\nneighba`
);
flushSync(() => {
btn2.click();
});
assert.htmlEqual(
target.innerHTML,
`<button>Activate</button><button>Toggle</button>\nzeeba\nzeeba`
);
}
});

@ -0,0 +1,49 @@
<script>
import { untrack } from 'svelte';
class Model {
data = $state();
constructor(data) {
this.data = data;
}
name = $derived(this.data?.name);
source = $derived(this.data?.source);
toggle() {
this.data.name = this.data.name === 'zeeba' ? 'neighba' : 'zeeba';
}
}
let model = $state(new Model({ name: 'zeeba', source: 'initial' }));
let setModel = (source) => {
let next = new Model({ name: 'zeeba', source });
model = next;
}
let needsSet = $state(false);
$effect(() => {
if(needsSet) {
setModel('effect');
untrack(() => {
needsSet = false;
});
}
});
let setWithEffect = () => {
needsSet = true;
};
let toggle = () => {
model.toggle();
}
</script>
<button onclick={setWithEffect}>Activate</button>
<button onclick={toggle}>Toggle</button>
{model.name}
{model.data.name}
Loading…
Cancel
Save