@@ -10,7 +10,8 @@ import {
10
10
INERT ,
11
11
RENDER_EFFECT ,
12
12
ROOT_EFFECT ,
13
- USER_EFFECT
13
+ USER_EFFECT ,
14
+ MAYBE_DIRTY
14
15
} from '#client/constants' ;
15
16
import { async_mode_flag } from '../../flags/index.js' ;
16
17
import { deferred , define_property } from '../../shared/utils.js' ;
@@ -27,7 +28,7 @@ import * as e from '../errors.js';
27
28
import { flush_tasks } from '../dom/task.js' ;
28
29
import { DEV } from 'esm-env' ;
29
30
import { invoke_error_boundary } from '../error-handling.js' ;
30
- import { mark_reactions , old_values } from './sources.js' ;
31
+ import { old_values } from './sources.js' ;
31
32
import { unlink_effect } from './effects.js' ;
32
33
import { unset_context } from './async.js' ;
33
34
@@ -146,6 +147,18 @@ export class Batch {
146
147
*/
147
148
#block_effects = [ ] ;
148
149
150
+ /**
151
+ * Deferred effects (which run after async work has completed) that are DIRTY
152
+ * @type {Effect[] }
153
+ */
154
+ #dirty_effects = [ ] ;
155
+
156
+ /**
157
+ * Deferred effects that are MAYBE_DIRTY
158
+ * @type {Effect[] }
159
+ */
160
+ #maybe_dirty_effects = [ ] ;
161
+
149
162
/**
150
163
* A set of branches that still exist, but will be destroyed when this batch
151
164
* is committed — we skip over these during `process`
@@ -221,10 +234,9 @@ export class Batch {
221
234
222
235
this . #deferred?. resolve ( ) ;
223
236
} else {
224
- // otherwise mark effects clean so they get scheduled on the next run
225
- for ( const e of this . #render_effects) set_signal_status ( e , CLEAN ) ;
226
- for ( const e of this . #effects) set_signal_status ( e , CLEAN ) ;
227
- for ( const e of this . #block_effects) set_signal_status ( e , CLEAN ) ;
237
+ this . #defer_effects( this . #render_effects) ;
238
+ this . #defer_effects( this . #effects) ;
239
+ this . #defer_effects( this . #block_effects) ;
228
240
}
229
241
230
242
if ( current_values ) {
@@ -271,15 +283,15 @@ export class Batch {
271
283
if ( ! skip && effect . fn !== null ) {
272
284
if ( is_branch ) {
273
285
effect . f ^= CLEAN ;
274
- } else if ( ( flags & EFFECT ) ! == 0 ) {
275
- this . #effects . push ( effect ) ;
276
- } else if ( async_mode_flag && ( flags & RENDER_EFFECT ) !== 0 ) {
277
- this . #render_effects . push ( effect ) ;
278
- } else if ( is_dirty ( effect ) ) {
279
- if ( ( flags & ASYNC ) !== 0 ) {
286
+ } else if ( ( flags & CLEAN ) = == 0 ) {
287
+ if ( ( flags & EFFECT ) !== 0 ) {
288
+ this . #effects . push ( effect ) ;
289
+ } else if ( async_mode_flag && ( flags & RENDER_EFFECT ) !== 0 ) {
290
+ this . #render_effects . push ( effect ) ;
291
+ } else if ( ( flags & ASYNC ) !== 0 ) {
280
292
var effects = effect . b ?. pending ? this . #boundary_async_effects : this . #async_effects;
281
293
effects . push ( effect ) ;
282
- } else {
294
+ } else if ( is_dirty ( effect ) ) {
283
295
if ( ( effect . f & BLOCK_EFFECT ) !== 0 ) this . #block_effects. push ( effect ) ;
284
296
update_effect ( effect ) ;
285
297
}
@@ -303,6 +315,21 @@ export class Batch {
303
315
}
304
316
}
305
317
318
+ /**
319
+ * @param {Effect[] } effects
320
+ */
321
+ #defer_effects( effects ) {
322
+ for ( const e of effects ) {
323
+ const target = ( e . f & DIRTY ) !== 0 ? this . #dirty_effects : this . #maybe_dirty_effects;
324
+ target . push ( e ) ;
325
+
326
+ // mark as clean so they get scheduled if they depend on pending async state
327
+ set_signal_status ( e , CLEAN ) ;
328
+ }
329
+
330
+ effects . length = 0 ;
331
+ }
332
+
306
333
/**
307
334
* Associate a change to a given source with the current
308
335
* batch, noting its previous and current values
@@ -380,8 +407,14 @@ export class Batch {
380
407
this . #pending -= 1 ;
381
408
382
409
if ( this . #pending === 0 ) {
383
- for ( const source of this . current . keys ( ) ) {
384
- mark_reactions ( source , DIRTY , false ) ;
410
+ for ( const e of this . #dirty_effects) {
411
+ set_signal_status ( e , DIRTY ) ;
412
+ schedule_effect ( e ) ;
413
+ }
414
+
415
+ for ( const e of this . #maybe_dirty_effects) {
416
+ set_signal_status ( e , MAYBE_DIRTY ) ;
417
+ schedule_effect ( e ) ;
385
418
}
386
419
387
420
this . #render_effects = [ ] ;
0 commit comments