diff --git a/documentation/docs/98-reference/.generated/client-errors.md b/documentation/docs/98-reference/.generated/client-errors.md index d47d0eb5cd..74a0674dba 100644 --- a/documentation/docs/98-reference/.generated/client-errors.md +++ b/documentation/docs/98-reference/.generated/client-errors.md @@ -149,7 +149,7 @@ This restriction only applies when using the `experimental.async` option, which ### fork_discarded ``` -Cannot commit a fork that was already committed or discarded (including as a result of a different fork being committed) +Cannot commit a fork that was already committed or discarded ``` ### fork_timing diff --git a/packages/svelte/messages/client-errors/errors.md b/packages/svelte/messages/client-errors/errors.md index 44afef58b4..b5fe51539d 100644 --- a/packages/svelte/messages/client-errors/errors.md +++ b/packages/svelte/messages/client-errors/errors.md @@ -114,7 +114,7 @@ This restriction only applies when using the `experimental.async` option, which ## fork_discarded -> Cannot commit a fork that was already committed or discarded (including as a result of a different fork being committed) +> Cannot commit a fork that was already committed or discarded ## fork_timing diff --git a/packages/svelte/src/internal/client/errors.js b/packages/svelte/src/internal/client/errors.js index 8341688ea6..2a433ed8f9 100644 --- a/packages/svelte/src/internal/client/errors.js +++ b/packages/svelte/src/internal/client/errors.js @@ -262,34 +262,34 @@ export function flush_sync_in_effect() { } /** - * Cannot create a fork inside an effect or when state changes are pending + * Cannot commit a fork that was already committed or discarded * @returns {never} */ -export function fork_timing() { +export function fork_discarded() { if (DEV) { - const error = new Error(`fork_timing\nCannot create a fork inside an effect or when state changes are pending\nhttps://svelte.dev/e/fork_timing`); + const error = new Error(`fork_discarded\nCannot commit a fork that was already committed or discarded\nhttps://svelte.dev/e/fork_discarded`); error.name = 'Svelte error'; throw error; } else { - throw new Error(`https://svelte.dev/e/fork_timing`); + throw new Error(`https://svelte.dev/e/fork_discarded`); } } /** - * Cannot commit a fork that was already committed or discarded (including as a result of a different fork being committed) + * Cannot create a fork inside an effect or when state changes are pending * @returns {never} */ -export function fork_discarded() { +export function fork_timing() { if (DEV) { - const error = new Error(`fork_discarded\nCannot commit a fork that was already committed or discarded (including as a result of a different fork being committed)\nhttps://svelte.dev/e/fork_discarded`); + const error = new Error(`fork_timing\nCannot create a fork inside an effect or when state changes are pending\nhttps://svelte.dev/e/fork_timing`); error.name = 'Svelte error'; throw error; } else { - throw new Error(`https://svelte.dev/e/fork_discarded`); + throw new Error(`https://svelte.dev/e/fork_timing`); } } diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index 35c2d30918..e96f90afb5 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -880,6 +880,9 @@ export function eager(fn) { * state changes will be reverted after the fork is initialised, then reapplied * if and when the fork is eventually committed. * + * When it becomes clear that a fork will _not_ be committed (e.g. because the + * user navigated elsewhere), it must be discarded to avoid leaking memory. + * * @param {() => void} fn * @returns {{ commit: () => void, discard: () => void }} */ @@ -912,11 +915,6 @@ export function fork(fn) { batch.is_fork = false; - // delete all other forks - for (const b of batches) { - if (b.is_fork) batches.delete(b); - } - // apply changes for (const [source, value] of batch.current) { source.v = value; diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 93c9fadb55..a05fd67587 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -460,6 +460,9 @@ declare module 'svelte' { * state changes will be reverted after the fork is initialised, then reapplied * if and when the fork is eventually committed. * + * When it becomes clear that a fork will _not_ be committed (e.g. because the + * user navigated elsewhere), it must be discarded to avoid leaking memory. + * * */ export function fork(fn: () => void): { commit: () => void;