fix: always reconnect deriveds in get, when appropriate (#17451)

* failing test

* fix: always reconnect deriveds in get, when appropriate

* shuffle code around a bit

* note to self
pull/17410/head
Rich Harris 2 weeks ago committed by GitHub
parent 2c23390286
commit ae224bea49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: always reconnect deriveds in get, when appropriate

@ -596,14 +596,14 @@ export function get(signal) {
}
}
if (is_destroying_effect) {
if (old_values.has(signal)) {
return old_values.get(signal);
}
if (is_destroying_effect && old_values.has(signal)) {
return old_values.get(signal);
}
if (is_derived) {
var derived = /** @type {Derived} */ (signal);
if (is_derived) {
var derived = /** @type {Derived} */ (signal);
if (is_destroying_effect) {
var value = derived.v;
// if the derived is dirty and has reactions, or depends on the values that just changed, re-execute
@ -619,14 +619,13 @@ export function get(signal) {
return value;
}
} else if (
is_derived &&
(!batch_values?.has(signal) || (current_batch?.is_fork && !effect_tracking()))
) {
derived = /** @type {Derived} */ (signal);
if (is_dirty(derived)) {
update_derived(derived);
// TODO this should probably just be `!batch_values?.has(derived)` — the second bit
// should be taken care of by clearing `batch_values` in `mark_reactions`?
if (!batch_values?.has(derived) || (current_batch?.is_fork && !effect_tracking())) {
if (is_dirty(derived)) {
update_derived(derived);
}
}
if (is_updating_effect && effect_tracking() && (derived.f & CONNECTED) === 0) {

@ -0,0 +1,24 @@
import { tick } from 'svelte';
import { test } from '../../test';
export default test({
compileOptions: {
dev: true
},
async test({ assert, target }) {
const [fork] = target.querySelectorAll('button');
fork.click();
await tick();
assert.htmlEqual(target.innerHTML, '<button>fork</button><button>false</button>');
const [, toggle] = target.querySelectorAll('button');
toggle.click();
await tick();
assert.htmlEqual(target.innerHTML, '<button>fork</button><button>true</button>');
}
});

@ -0,0 +1,26 @@
<script>
import { fork } from 'svelte';
let condition = $state(false);
let checked = $state(false);
const d = $derived({ checked });
</script>
<button onclick={() => {
fork(() => {
condition = true;
}).commit();
}}>fork</button>
{#if condition}
<!-- in dev, snippet arguments are read eagerly, outside a tracking context -->
<!-- this test checks that doing so doesn't prevent the derived from connecting -->
{#snippet foo({ checked })}
{checked}
{/snippet}
<button onclick={() => (checked = !checked)}>
{@render foo(d)}
</button>
{/if}
Loading…
Cancel
Save