Skip to content

Commit 39a7ae8

Browse files
committed
fix: remove memory leak
1 parent f1550b2 commit 39a7ae8

File tree

5 files changed

+59
-25
lines changed

5 files changed

+59
-25
lines changed

packages/svelte/src/internal/client/runtime.js

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,6 @@ export function derived(init) {
13081308
create_computation_signal(flags | CLEAN, UNINITIALIZED, current_block)
13091309
);
13101310
signal.i = init;
1311-
bind_signal_to_component_context(signal);
13121311
signal.e = default_equals;
13131312
if (current_consumer !== null) {
13141313
push_reference(current_consumer, signal);
@@ -1335,26 +1334,7 @@ export function derived_safe_equal(init) {
13351334
*/
13361335
/*#__NO_SIDE_EFFECTS__*/
13371336
export function source(initial_value) {
1338-
const source = create_source_signal(SOURCE | CLEAN, initial_value);
1339-
bind_signal_to_component_context(source);
1340-
return source;
1341-
}
1342-
1343-
/**
1344-
* This function binds a signal to the component context, so that we can fire
1345-
* beforeUpdate/afterUpdate callbacks at the correct time etc
1346-
* @param {import('./types.js').Signal} signal
1347-
*/
1348-
function bind_signal_to_component_context(signal) {
1349-
if (current_component_context === null || !current_component_context.r) return;
1350-
1351-
const signals = current_component_context.d;
1352-
1353-
if (signals) {
1354-
signals.push(signal);
1355-
} else {
1356-
current_component_context.d = [signal];
1357-
}
1337+
return create_source_signal(SOURCE | CLEAN, initial_value);
13581338
}
13591339

13601340
/**
@@ -1366,6 +1346,19 @@ function bind_signal_to_component_context(signal) {
13661346
export function mutable_source(initial_value) {
13671347
const s = source(initial_value);
13681348
s.e = safe_equal;
1349+
1350+
// bind the signal to the component context, in case we need to
1351+
// track updates to trigger beforeUpdate/afterUpdate callbacks
1352+
if (current_component_context && !current_component_context.r) {
1353+
const signals = current_component_context.d;
1354+
1355+
if (signals) {
1356+
signals.push(s);
1357+
} else {
1358+
current_component_context.d = [s];
1359+
}
1360+
}
1361+
13691362
return s;
13701363
}
13711364

@@ -1971,10 +1964,7 @@ function observe_all(context) {
19711964
for (const signal of context.d) get(signal);
19721965
}
19731966

1974-
const props = get_descriptors(context.s);
1975-
for (const descriptor of Object.values(props)) {
1976-
if (descriptor.get) descriptor.get();
1977-
}
1967+
deep_read(context.s);
19781968
}
19791969

19801970
/**
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<svelte:options runes={false} />
2+
3+
<script>
4+
import { beforeUpdate } from 'svelte';
5+
import { logs } from './logs.js'
6+
7+
export let object;
8+
9+
beforeUpdate(() => {
10+
logs.push('changed');
11+
});
12+
</script>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
import { logs } from './logs.js';
4+
5+
export default test({
6+
html: `<button>clicks: 0</button>`,
7+
8+
test({ assert, target }) {
9+
const btn = target.querySelector('button');
10+
11+
flushSync(() => btn?.click());
12+
13+
assert.htmlEqual(target.innerHTML, `<button>clicks: 1</button>`);
14+
assert.deepEqual(logs, ['changed', 'changed']);
15+
},
16+
17+
after_test() {
18+
logs.length = 0;
19+
}
20+
});
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/** @type {any[]} */
2+
export const logs = [];
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
import Child from './Child.svelte';
3+
let object = $state({ count: 0 })
4+
</script>
5+
6+
<button onclick={() => object.count += 1}>
7+
clicks: {object.count}
8+
</button>
9+
10+
<Child {object} />

0 commit comments

Comments
 (0)