@@ -70,7 +70,7 @@ let last_scheduled_effect = null;
7070
7171let is_flushing = false ;
7272
73- let flushing_sync = false ;
73+ export let flushing_sync = false ;
7474
7575export class Batch {
7676 /**
@@ -204,9 +204,22 @@ export class Batch {
204204 this . #effects = [ ] ;
205205 this . #block_effects = [ ] ;
206206
207+ // If sources are written to, then work needs to happen in a separate batch, else prior sources would be mixed with
208+ // newly updated sources, which could lead to infinite loops when effects run over and over again.
209+ current_batch = null ;
210+
207211 flush_queued_effects ( render_effects ) ;
208212 flush_queued_effects ( effects ) ;
209213
214+ // Reinstate the current batch if there was no new one created, as `process()` runs in a loop in `flush_effects()`.
215+ // That method expects `current_batch` to be set, and could run the loop again if effects result in new effects
216+ // being scheduled but without writes happening in which case no new batch is created.
217+ if ( current_batch === null ) {
218+ current_batch = this ;
219+ } else {
220+ batches . delete ( this ) ;
221+ }
222+
210223 this . #deferred?. resolve ( ) ;
211224 } else {
212225 // otherwise mark effects clean so they get scheduled on the next run
@@ -551,7 +564,6 @@ function flush_queued_effects(effects) {
551564
552565 if ( ( effect . f & ( DESTROYED | INERT ) ) === 0 && is_dirty ( effect ) ) {
553566 var wv = write_version ;
554- var current_size = /** @type {Batch } */ ( current_batch ) . current . size ;
555567
556568 update_effect ( effect ) ;
557569
@@ -575,21 +587,6 @@ function flush_queued_effects(effects) {
575587 // if state is written in a user effect, abort and re-schedule, lest we run
576588 // effects that should be removed as a result of the state change
577589 if ( write_version > wv && ( effect . f & USER_EFFECT ) !== 0 ) {
578- // Work needs to happen in a separate batch, else prior sources would be mixed with
579- // newly updated sources, which could lead to infinite loops when effects run over and over again.
580- // We need to bring over the just written sources though to correctly mark the right reactions as dirty.
581- var old_batch = /** @type {Batch } */ ( current_batch ) ;
582- batches . delete ( old_batch ) ;
583- current_batch = null ;
584- var new_batch = Batch . ensure ( ! flushing_sync ) ;
585- var current_idx = 0 ;
586- // We're taking advantage of the spec here which says that entries in a Map are traversed by insertion order
587- for ( const source of old_batch . current ) {
588- if ( current_idx >= current_size ) {
589- new_batch . capture ( source [ 0 ] , source [ 1 ] ) ;
590- }
591- current_idx ++ ;
592- }
593590 break ;
594591 }
595592 }
0 commit comments