Skip to content

Commit 657ec89

Browse files
authored
fix: ignore fork discard() after commit() (#17034)
* fix: ignore fork `discard()` after `commit()` * fix message
1 parent 875a041 commit 657ec89

File tree

5 files changed

+24
-11
lines changed

5 files changed

+24
-11
lines changed

.changeset/twenty-onions-attack.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: ignore fork `discard()` after `commit()`

documentation/docs/98-reference/.generated/client-errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ This restriction only applies when using the `experimental.async` option, which
149149
### fork_discarded
150150

151151
```
152-
Cannot commit a fork that was already committed or discarded
152+
Cannot commit a fork that was already discarded
153153
```
154154

155155
### fork_timing

packages/svelte/messages/client-errors/errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ This restriction only applies when using the `experimental.async` option, which
114114

115115
## fork_discarded
116116

117-
> Cannot commit a fork that was already committed or discarded
117+
> Cannot commit a fork that was already discarded
118118
119119
## fork_timing
120120

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,12 @@ export function flush_sync_in_effect() {
262262
}
263263

264264
/**
265-
* Cannot commit a fork that was already committed or discarded
265+
* Cannot commit a fork that was already discarded
266266
* @returns {never}
267267
*/
268268
export function fork_discarded() {
269269
if (DEV) {
270-
const error = new Error(`fork_discarded\nCannot commit a fork that was already committed or discarded\nhttps://svelte.dev/e/fork_discarded`);
270+
const error = new Error(`fork_discarded\nCannot commit a fork that was already discarded\nhttps://svelte.dev/e/fork_discarded`);
271271

272272
error.name = 'Svelte error';
273273

packages/svelte/src/internal/client/reactivity/batch.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -913,28 +913,36 @@ export function fork(fn) {
913913
e.fork_timing();
914914
}
915915

916-
const batch = Batch.ensure();
916+
var batch = Batch.ensure();
917917
batch.is_fork = true;
918918

919-
const settled = batch.settled();
919+
var committed = false;
920+
var settled = batch.settled();
920921

921922
flushSync(fn);
922923

923924
// revert state changes
924-
for (const [source, value] of batch.previous) {
925+
for (var [source, value] of batch.previous) {
925926
source.v = value;
926927
}
927928

928929
return {
929930
commit: async () => {
931+
if (committed) {
932+
await settled;
933+
return;
934+
}
935+
930936
if (!batches.has(batch)) {
931937
e.fork_discarded();
932938
}
933939

940+
committed = true;
941+
934942
batch.is_fork = false;
935943

936944
// apply changes
937-
for (const [source, value] of batch.current) {
945+
for (var [source, value] of batch.current) {
938946
source.v = value;
939947
}
940948

@@ -945,9 +953,9 @@ export function fork(fn) {
945953
// TODO maybe there's a better implementation?
946954
flushSync(() => {
947955
/** @type {Set<Effect>} */
948-
const eager_effects = new Set();
956+
var eager_effects = new Set();
949957

950-
for (const source of batch.current.keys()) {
958+
for (var source of batch.current.keys()) {
951959
mark_eager_effects(source, eager_effects);
952960
}
953961

@@ -959,7 +967,7 @@ export function fork(fn) {
959967
await settled;
960968
},
961969
discard: () => {
962-
if (batches.has(batch)) {
970+
if (!committed && batches.has(batch)) {
963971
batches.delete(batch);
964972
batch.discard();
965973
}

0 commit comments

Comments
 (0)