diff --git a/.changeset/major-towns-grab.md b/.changeset/major-towns-grab.md
new file mode 100644
index 0000000000..de66b70313
--- /dev/null
+++ b/.changeset/major-towns-grab.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: always reconnect deriveds in get, when appropriate
diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js
index 52b24030fa..82c5f5a06f 100644
--- a/packages/svelte/src/internal/client/runtime.js
+++ b/packages/svelte/src/internal/client/runtime.js
@@ -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) {
diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-snippet-dev/_config.js b/packages/svelte/tests/runtime-runes/samples/async-fork-snippet-dev/_config.js
new file mode 100644
index 0000000000..2fb00562f5
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-fork-snippet-dev/_config.js
@@ -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, '');
+
+ const [, toggle] = target.querySelectorAll('button');
+
+ toggle.click();
+ await tick();
+
+ assert.htmlEqual(target.innerHTML, '');
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-snippet-dev/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-fork-snippet-dev/main.svelte
new file mode 100644
index 0000000000..6945fcd153
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-fork-snippet-dev/main.svelte
@@ -0,0 +1,26 @@
+
+
+
+
+{#if condition}
+
+
+ {#snippet foo({ checked })}
+ {checked}
+ {/snippet}
+
+
+{/if}