diff --git a/.changeset/curvy-flies-exercise.md b/.changeset/curvy-flies-exercise.md
new file mode 100644
index 0000000000..bcdbe1b448
--- /dev/null
+++ b/.changeset/curvy-flies-exercise.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: ensure correct context for action update/destroy functions
diff --git a/packages/svelte/src/internal/client/dom/elements/actions.js b/packages/svelte/src/internal/client/dom/elements/actions.js
index 669a14c057..50f946b93a 100644
--- a/packages/svelte/src/internal/client/dom/elements/actions.js
+++ b/packages/svelte/src/internal/client/dom/elements/actions.js
@@ -11,9 +11,8 @@ import { deep_read_state, untrack } from '../../runtime.js';
export function action(dom, action, get_value) {
effect(() => {
var payload = untrack(() => action(dom, get_value?.()) || {});
- var update = payload?.update;
- if (get_value && update) {
+ if (get_value && payload?.update) {
var inited = false;
render_effect(() => {
@@ -25,13 +24,15 @@ export function action(dom, action, get_value) {
deep_read_state(value);
if (inited) {
- /** @type {Function} */ (update)(value);
+ /** @type {Function} */ (payload.update)(value);
}
});
inited = true;
}
- return payload?.destroy;
+ if (payload?.destroy) {
+ return () => /** @type {Function} */ (payload.destroy)();
+ }
});
}
diff --git a/packages/svelte/tests/runtime-runes/samples/action-context/_config.js b/packages/svelte/tests/runtime-runes/samples/action-context/_config.js
new file mode 100644
index 0000000000..87e9842d9a
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/action-context/_config.js
@@ -0,0 +1,22 @@
+import { ok, test } from '../../test';
+import { flushSync, tick } from 'svelte';
+import { log } from './log.js';
+
+export default test({
+ html: ``,
+
+ before_test() {
+ log.length = 0;
+ },
+
+ async test({ assert, target }) {
+ const btn = target.querySelector('button');
+ ok(btn);
+
+ flushSync(() => btn.click());
+ assert.deepEqual(log, ['update', 0, 1]);
+
+ flushSync(() => btn.click());
+ assert.deepEqual(log, ['update', 0, 1, 'destroy', 1]);
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/action-context/log.js b/packages/svelte/tests/runtime-runes/samples/action-context/log.js
new file mode 100644
index 0000000000..d3df521f4d
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/action-context/log.js
@@ -0,0 +1,2 @@
+/** @type {any[]} */
+export const log = [];
diff --git a/packages/svelte/tests/runtime-runes/samples/action-context/main.svelte b/packages/svelte/tests/runtime-runes/samples/action-context/main.svelte
new file mode 100644
index 0000000000..ef8f7894cc
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/action-context/main.svelte
@@ -0,0 +1,28 @@
+
+
+{#if count < 2}
+
+{/if}