diff --git a/.changeset/long-moles-join.md b/.changeset/long-moles-join.md
new file mode 100644
index 000000000000..92c3d7bf9d7e
--- /dev/null
+++ b/.changeset/long-moles-join.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: ensure tracking returns true, even if in unowned
diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js
index eab6c767f868..9d7b5e9de624 100644
--- a/packages/svelte/src/internal/client/reactivity/effects.js
+++ b/packages/svelte/src/internal/client/reactivity/effects.js
@@ -164,13 +164,7 @@ function create_effect(type, fn, sync, push = true) {
* @returns {boolean}
*/
export function effect_tracking() {
- if (active_reaction === null || untracking) {
- return false;
- }
-
- // If it's skipped, that's because we're inside an unowned
- // that is not being tracked by another reaction
- return !skip_reaction;
+ return active_reaction !== null && !untracking;
}
/**
diff --git a/packages/svelte/tests/runtime-runes/samples/effect-tracking-unowned/_config.js b/packages/svelte/tests/runtime-runes/samples/effect-tracking-unowned/_config.js
new file mode 100644
index 000000000000..749b9997c2c5
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/effect-tracking-unowned/_config.js
@@ -0,0 +1,16 @@
+import { flushSync } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target, logs }) {
+ const b1 = target.querySelector('button');
+
+ b1?.click();
+ flushSync();
+
+ assert.htmlEqual(
+ target.innerHTML,
+ `
Text: new message
` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/effect-tracking-unowned/main.svelte b/packages/svelte/tests/runtime-runes/samples/effect-tracking-unowned/main.svelte new file mode 100644 index 000000000000..3c16e3c0366c --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/effect-tracking-unowned/main.svelte @@ -0,0 +1,12 @@ + + +Text: {text}
+