fix: remove `source.updated` stack traces after `flush` (#18196)

Noticed that we're not actually doing anything with `source_stacks` — we
shadow the module-level declaration in `flush`, which means we just keep
appending to it and then clearing a different (and empty) set. As a
result, any source that ever gets an `updated` property never gets rid
of it. This probably causes a memory leak?

Anyway, this fixes it.

### Before submitting the PR, please make sure you do the following

- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).

### Tests and linting

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
pull/18201/head
Rich Harris 3 months ago committed by GitHub
parent e00944ffd1
commit 9ffc13d7c3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: reset `source.updated` stack traces after `flush`

@ -85,7 +85,9 @@ export let collected_effects = null;
export let legacy_updates = null;
var flush_count = 0;
var source_stacks = DEV ? new Set() : null;
/** @type {Set<Value>} */
var source_stacks = new Set();
let uid = 1;
@ -273,6 +275,14 @@ export class Batch {
infinite_loop_guard();
}
if (DEV) {
// track all the values that were updated during this flush,
// so that they can be reset afterwards
for (const value of this.current.keys()) {
source_stacks.add(value);
}
}
// we only reschedule previously-deferred effects if we expect
// to be able to run them after processing the batch
if (!this.#is_deferred()) {
@ -377,12 +387,6 @@ export class Batch {
}
if (next_batch !== null) {
if (DEV) {
for (const source of this.current.keys()) {
/** @type {Set<Source>} */ (source_stacks).add(source);
}
}
next_batch.#process();
}
}
@ -481,9 +485,11 @@ export class Batch {
}
flush() {
var source_stacks = DEV ? new Set() : null;
try {
if (DEV) {
source_stacks.clear();
}
is_processing = true;
current_batch = this;
@ -501,7 +507,7 @@ export class Batch {
old_values.clear();
if (DEV) {
for (const source of /** @type {Set<Source>} */ (source_stacks)) {
for (const source of source_stacks) {
source.updated = null;
}
}

Loading…
Cancel
Save