File tree Expand file tree Collapse file tree 4 files changed +38
-18
lines changed
src/internal/client/reactivity
tests/runtime-runes/samples/async-resolve-stale Expand file tree Collapse file tree 4 files changed +38
-18
lines changed Original file line number Diff line number Diff line change 1+ ---
2+ ' svelte ' : patch
3+ ---
4+
5+ fix: prevent re-activated stale batches from break reactivity
Original file line number Diff line number Diff line change @@ -421,6 +421,13 @@ export class Batch {
421421 }
422422
423423 static ensure ( ) {
424+ if ( current_batch !== null && ! batches . has ( current_batch ) ) {
425+ // A previously committed batch was reactivated via async `restore`.
426+ // Treat it as inactive so a new batch can be created to process updates.
427+ current_batch = null ;
428+ batch_values = null ;
429+ }
430+
424431 if ( current_batch === null ) {
425432 const batch = ( current_batch = new Batch ( ) ) ;
426433 batches . add ( current_batch ) ;
Original file line number Diff line number Diff line change @@ -21,5 +21,9 @@ export default test({
2121 input . dispatchEvent ( new Event ( 'input' , { bubbles : true } ) ) ;
2222 await macrotask ( 6 ) ;
2323 assert . htmlEqual ( target . innerHTML , '<input> 3 | 12' ) ;
24+ input . value = '' ;
25+ input . dispatchEvent ( new Event ( 'input' , { bubbles : true } ) ) ;
26+ await macrotask ( ) ;
27+ assert . htmlEqual ( target . innerHTML , '<input> 4 | ' ) ;
2428 }
2529} ) ;
Original file line number Diff line number Diff line change 11<script >
22 let count = $state (0 );
33 let value = $state (' ' );
4- let prev;
54
6- function asd (v ) {
7- const r = Promise .withResolvers ();
5+ let resolver;
86
9- if (prev || v === ' ' ) {
10- Promise .resolve ().then (async () => {
11- count++ ;
12- r .resolve (v);
13- await new Promise (r => setTimeout (r, 0 ));
14- // TODO with a microtask like below it still throws a mutation error
15- // await Promise.resolve();
16- prev? .resolve ();
17- });
18- } else {
19- prev = Promise .withResolvers ();
20- prev .promise .then (() => {
21- count++ ;
22- r .resolve (v)
23- });
7+ function asd (v ) {
8+ let r = Promise .withResolvers ();
9+
10+ function update_and_resolve (){
11+ count++ ;
12+ r .resolve (v);
2413 }
2514
15+ // make sure the second promise resolve before the first one
16+ if (resolver){
17+ new Promise (r => {
18+ setTimeout (r);
19+ }).then (update_and_resolve).then (()=> {
20+ setTimeout (()=> {
21+ resolver ();
22+ resolver = null ;
23+ });
24+ });
25+ }else if (v){
26+ resolver = update_and_resolve;
27+ }else {
28+ Promise .resolve ().then (update_and_resolve);
29+ }
2630 return r .promise ;
2731 }
2832
You can’t perform that action at this time.
0 commit comments