@@ -247,25 +247,88 @@ export function createReactiveSystem({
247
247
}
248
248
sub . flags &= ~ SubscriberFlags . Tracking ;
249
249
} ,
250
- checkDirty,
251
250
/**
252
- * Updates the computed subscriber if necessary before its value is accessed .
251
+ * Recursively checks and updates all computed subscribers marked as pending .
253
252
*
254
- * If the subscriber is marked Dirty or PendingComputed, this function runs
255
- * the provided updateComputed logic and triggers a shallowPropagate for any
256
- * downstream subscribers if an actual update occurs .
253
+ * It traverses the linked structure using a stack mechanism. For each computed
254
+ * subscriber in a pending state, updateComputed is called and shallowPropagate
255
+ * is triggered if a value changes. Returns whether any updates occurred .
257
256
*
258
- * @param computed - The computed subscriber to update .
259
- * @param flags - The current flag set for this subscriber .
257
+ * @param link - The starting link representing a sequence of pending computeds .
258
+ * @returns `true` if a computed was updated, otherwise `false` .
260
259
*/
261
- processComputedUpdate ( computed : Dependency & Subscriber , flags : SubscriberFlags ) : void {
262
- if ( flags & SubscriberFlags . Dirty ) {
263
- updateComputed ( computed ) ;
264
- } else if ( checkDirty ( computed . deps ! ) ) {
265
- updateComputed ( computed ) ;
266
- } else {
267
- computed . flags = flags & ~ SubscriberFlags . Pending ;
268
- }
260
+ checkDirty ( link : Link ) : boolean {
261
+ let stack = 0 ;
262
+ let dirty : boolean ;
263
+
264
+ top: do {
265
+ dirty = false ;
266
+ const dep = link . dep ;
267
+
268
+ if ( dep . version !== link . version ) {
269
+ dirty = true ;
270
+ } else if ( 'flags' in dep ) {
271
+ const depFlags = dep . flags ;
272
+ if ( ( depFlags & ( SubscriberFlags . Computed | SubscriberFlags . Dirty ) ) === ( SubscriberFlags . Computed | SubscriberFlags . Dirty ) ) {
273
+ if ( updateComputed ( dep ) ) {
274
+ dirty = true ;
275
+ }
276
+ } else if ( ( depFlags & ( SubscriberFlags . Computed | SubscriberFlags . Pending ) ) === ( SubscriberFlags . Computed | SubscriberFlags . Pending ) ) {
277
+ const depSubs = dep . subs ! ;
278
+ if ( depSubs . nextSub !== undefined ) {
279
+ depSubs . prevSub = link ;
280
+ }
281
+ link = dep . deps ! ;
282
+ ++ stack ;
283
+ continue ;
284
+ }
285
+ }
286
+
287
+ if ( ! dirty && link . nextDep !== undefined ) {
288
+ link = link . nextDep ;
289
+ continue ;
290
+ }
291
+
292
+ if ( stack ) {
293
+ let sub = link . sub as Dependency & Subscriber ;
294
+ do {
295
+ -- stack ;
296
+ const subSubs = sub . subs ! ;
297
+
298
+ if ( dirty ) {
299
+ if ( updateComputed ( sub ) ) {
300
+ if ( ( link = subSubs . prevSub ! ) !== undefined ) {
301
+ subSubs . prevSub = undefined ;
302
+ sub = link . sub as Dependency & Subscriber ;
303
+ } else {
304
+ sub = subSubs . sub as Dependency & Subscriber ;
305
+ }
306
+ continue ;
307
+ }
308
+ } else {
309
+ sub . flags &= ~ SubscriberFlags . Pending ;
310
+ }
311
+
312
+ if ( ( link = subSubs . prevSub ! ) !== undefined ) {
313
+ subSubs . prevSub = undefined ;
314
+ if ( link . nextDep !== undefined ) {
315
+ link = link . nextDep ;
316
+ continue top;
317
+ }
318
+ sub = link . sub as Dependency & Subscriber ;
319
+ } else {
320
+ if ( ( link = subSubs . nextDep ! ) !== undefined ) {
321
+ continue top;
322
+ }
323
+ sub = subSubs . sub as Dependency & Subscriber ;
324
+ }
325
+
326
+ dirty = false ;
327
+ } while ( stack ) ;
328
+ }
329
+
330
+ return dirty ;
331
+ } while ( true ) ;
269
332
} ,
270
333
/**
271
334
* Ensures all pending internal effects for the given subscriber are processed.
@@ -371,90 +434,6 @@ export function createReactiveSystem({
371
434
return newLink ;
372
435
}
373
436
374
- /**
375
- * Recursively checks and updates all computed subscribers marked as pending.
376
- *
377
- * It traverses the linked structure using a stack mechanism. For each computed
378
- * subscriber in a pending state, updateComputed is called and shallowPropagate
379
- * is triggered if a value changes. Returns whether any updates occurred.
380
- *
381
- * @param link - The starting link representing a sequence of pending computeds.
382
- * @returns `true` if a computed was updated, otherwise `false`.
383
- */
384
- function checkDirty ( link : Link ) : boolean {
385
- let stack = 0 ;
386
- let dirty : boolean ;
387
-
388
- top: do {
389
- dirty = false ;
390
- const dep = link . dep ;
391
-
392
- if ( dep . version !== link . version ) {
393
- dirty = true ;
394
- } else if ( 'flags' in dep ) {
395
- const depFlags = dep . flags ;
396
- if ( ( depFlags & ( SubscriberFlags . Computed | SubscriberFlags . Dirty ) ) === ( SubscriberFlags . Computed | SubscriberFlags . Dirty ) ) {
397
- if ( updateComputed ( dep ) ) {
398
- dirty = true ;
399
- }
400
- } else if ( ( depFlags & ( SubscriberFlags . Computed | SubscriberFlags . Pending ) ) === ( SubscriberFlags . Computed | SubscriberFlags . Pending ) ) {
401
- const depSubs = dep . subs ! ;
402
- if ( depSubs . nextSub !== undefined ) {
403
- depSubs . prevSub = link ;
404
- }
405
- link = dep . deps ! ;
406
- ++ stack ;
407
- continue ;
408
- }
409
- }
410
-
411
- if ( ! dirty && link . nextDep !== undefined ) {
412
- link = link . nextDep ;
413
- continue ;
414
- }
415
-
416
- if ( stack ) {
417
- let sub = link . sub as Dependency & Subscriber ;
418
- do {
419
- -- stack ;
420
- const subSubs = sub . subs ! ;
421
-
422
- if ( dirty ) {
423
- if ( updateComputed ( sub ) ) {
424
- if ( ( link = subSubs . prevSub ! ) !== undefined ) {
425
- subSubs . prevSub = undefined ;
426
- sub = link . sub as Dependency & Subscriber ;
427
- } else {
428
- sub = subSubs . sub as Dependency & Subscriber ;
429
- }
430
- continue ;
431
- }
432
- } else {
433
- sub . flags &= ~ SubscriberFlags . Pending ;
434
- }
435
-
436
- if ( ( link = subSubs . prevSub ! ) !== undefined ) {
437
- subSubs . prevSub = undefined ;
438
- if ( link . nextDep !== undefined ) {
439
- link = link . nextDep ;
440
- continue top;
441
- }
442
- sub = link . sub as Dependency & Subscriber ;
443
- } else {
444
- if ( ( link = subSubs . nextDep ! ) !== undefined ) {
445
- continue top;
446
- }
447
- sub = subSubs . sub as Dependency & Subscriber ;
448
- }
449
-
450
- dirty = false ;
451
- } while ( stack ) ;
452
- }
453
-
454
- return dirty ;
455
- } while ( true ) ;
456
- }
457
-
458
437
/**
459
438
* Verifies whether the given link is valid for the specified subscriber.
460
439
*
@@ -526,8 +505,8 @@ export function createReactiveSystem({
526
505
527
506
function warming ( sub : Subscriber & Dependency ) {
528
507
sub . flags &= ~ SubscriberFlags . Cold ;
529
- let link = sub . deps ;
530
- while ( link !== undefined ) {
508
+ let link = sub . deps ! ;
509
+ do {
531
510
const dep = link . dep as Dependency | Dependency & Subscriber ;
532
511
if ( dep . subs === undefined ) {
533
512
dep . subs = link ;
@@ -545,14 +524,13 @@ export function createReactiveSystem({
545
524
warming ( dep ) ;
546
525
}
547
526
}
548
- link = link . nextDep ;
549
- }
527
+ } while ( ( link = link . nextDep ! ) !== undefined ) ;
550
528
}
551
529
552
530
function cooling ( sub : Subscriber & Dependency ) {
553
531
sub . flags |= SubscriberFlags . Cold ;
554
- let link = sub . deps ;
555
- while ( link !== undefined ) {
532
+ let link = sub . deps ! ;
533
+ do {
556
534
const dep = link . dep ;
557
535
const nextSub = link . nextSub ;
558
536
const prevSub = link . prevSub ;
@@ -576,10 +554,10 @@ export function createReactiveSystem({
576
554
dep . subs === undefined
577
555
&& 'flags' in dep
578
556
&& dep . flags & SubscriberFlags . Computed
557
+ && dep . deps !== undefined
579
558
) {
580
559
cooling ( dep ) ;
581
560
}
582
- link = link . nextDep ;
583
- }
561
+ } while ( ( link = link . nextDep ! ) !== undefined ) ;
584
562
}
585
563
}
0 commit comments