From 6636f748ae770e905ca9e88e9a921b4bc854164c Mon Sep 17 00:00:00 2001 From: 7nik Date: Sat, 14 Jun 2025 18:19:42 +0300 Subject: [PATCH] fix: prevent memory leaking signals in legacy mode (#16145) * fix: prevent memory leaking signals in legacy mode * format * fix --------- Co-authored-by: 7nik --- .changeset/soft-oranges-approve.md | 5 +++++ packages/svelte/src/internal/client/dom/blocks/await.js | 6 ++++-- packages/svelte/src/internal/client/dom/blocks/each.js | 2 +- packages/svelte/src/internal/client/reactivity/sources.js | 4 ++-- packages/svelte/src/legacy/legacy-client.js | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 .changeset/soft-oranges-approve.md diff --git a/.changeset/soft-oranges-approve.md b/.changeset/soft-oranges-approve.md new file mode 100644 index 0000000000..f759c128c0 --- /dev/null +++ b/.changeset/soft-oranges-approve.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: prevent memory leaking signals in legacy mode diff --git a/packages/svelte/src/internal/client/dom/blocks/await.js b/packages/svelte/src/internal/client/dom/blocks/await.js index 99bdc0000c..47df5fc9a5 100644 --- a/packages/svelte/src/internal/client/dom/blocks/await.js +++ b/packages/svelte/src/internal/client/dom/blocks/await.js @@ -58,8 +58,10 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) { /** @type {Effect | null} */ var catch_effect; - var input_source = (runes ? source : mutable_source)(/** @type {V} */ (undefined)); - var error_source = (runes ? source : mutable_source)(undefined); + var input_source = runes + ? source(/** @type {V} */ (undefined)) + : mutable_source(/** @type {V} */ (undefined), false, false); + var error_source = runes ? source(undefined) : mutable_source(undefined, false, false); var resolved = false; /** diff --git a/packages/svelte/src/internal/client/dom/blocks/each.js b/packages/svelte/src/internal/client/dom/blocks/each.js index 954dcb2214..b638a6d2da 100644 --- a/packages/svelte/src/internal/client/dom/blocks/each.js +++ b/packages/svelte/src/internal/client/dom/blocks/each.js @@ -521,7 +521,7 @@ function create_item( var reactive = (flags & EACH_ITEM_REACTIVE) !== 0; var mutable = (flags & EACH_ITEM_IMMUTABLE) === 0; - var v = reactive ? (mutable ? mutable_source(value) : source(value)) : value; + var v = reactive ? (mutable ? mutable_source(value, false, false) : source(value)) : value; var i = (flags & EACH_INDEX_REACTIVE) === 0 ? index : source(index); if (DEV && reactive) { diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index 40a3e4e77f..56f4138252 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -97,7 +97,7 @@ export function state(v, stack) { * @returns {Source} */ /*#__NO_SIDE_EFFECTS__*/ -export function mutable_source(initial_value, immutable = false) { +export function mutable_source(initial_value, immutable = false, trackable = true) { const s = source(initial_value); if (!immutable) { s.equals = safe_equals; @@ -105,7 +105,7 @@ export function mutable_source(initial_value, immutable = false) { // bind the signal to the component context, in case we need to // track updates to trigger beforeUpdate/afterUpdate callbacks - if (legacy_mode_flag && component_context !== null && component_context.l !== null) { + if (legacy_mode_flag && trackable && component_context !== null && component_context.l !== null) { (component_context.l.s ??= []).push(s); } diff --git a/packages/svelte/src/legacy/legacy-client.js b/packages/svelte/src/legacy/legacy-client.js index bb9a5a9c03..45c478ecab 100644 --- a/packages/svelte/src/legacy/legacy-client.js +++ b/packages/svelte/src/legacy/legacy-client.js @@ -82,7 +82,7 @@ class Svelte4Component { * @param {unknown} value */ var add_source = (key, value) => { - var s = mutable_source(value); + var s = mutable_source(value, false, false); sources.set(key, s); return s; };