fix: ignore fork `discard()` after `commit()`

pull/17034/head
Rich Harris 1 week ago
parent 875a04170e
commit 33450bc075

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ignore fork `discard()` after `commit()`

@ -913,28 +913,36 @@ export function fork(fn) {
e.fork_timing(); e.fork_timing();
} }
const batch = Batch.ensure(); var batch = Batch.ensure();
batch.is_fork = true; batch.is_fork = true;
const settled = batch.settled(); var committed = false;
var settled = batch.settled();
flushSync(fn); flushSync(fn);
// revert state changes // revert state changes
for (const [source, value] of batch.previous) { for (var [source, value] of batch.previous) {
source.v = value; source.v = value;
} }
return { return {
commit: async () => { commit: async () => {
if (committed) {
await settled;
return;
}
if (!batches.has(batch)) { if (!batches.has(batch)) {
e.fork_discarded(); e.fork_discarded();
} }
committed = true;
batch.is_fork = false; batch.is_fork = false;
// apply changes // apply changes
for (const [source, value] of batch.current) { for (var [source, value] of batch.current) {
source.v = value; source.v = value;
} }
@ -945,9 +953,9 @@ export function fork(fn) {
// TODO maybe there's a better implementation? // TODO maybe there's a better implementation?
flushSync(() => { flushSync(() => {
/** @type {Set<Effect>} */ /** @type {Set<Effect>} */
const eager_effects = new Set(); var eager_effects = new Set();
for (const source of batch.current.keys()) { for (var source of batch.current.keys()) {
mark_eager_effects(source, eager_effects); mark_eager_effects(source, eager_effects);
} }
@ -959,7 +967,7 @@ export function fork(fn) {
await settled; await settled;
}, },
discard: () => { discard: () => {
if (batches.has(batch)) { if (!committed && batches.has(batch)) {
batches.delete(batch); batches.delete(batch);
batch.discard(); batch.discard();
} }

Loading…
Cancel
Save