@@ -236,7 +236,7 @@ import {
236
236
markSkippedUpdateLanes ,
237
237
getWorkInProgressRoot ,
238
238
pushRenderLanes ,
239
- getWorkInProgressTransitions ,
239
+ setRootPendingSuspenseBoundaries ,
240
240
} from './ReactFiberWorkLoop.old' ;
241
241
import { setWorkInProgressVersion } from './ReactMutableSource.old' ;
242
242
import { pushCacheProvider , CacheContext } from './ReactFiberCacheComponent.old' ;
@@ -256,6 +256,7 @@ import {
256
256
getSuspendedCache ,
257
257
pushTransition ,
258
258
getOffscreenDeferredCache ,
259
+ getSuspendedTransitions ,
259
260
} from './ReactFiberTransition.old' ;
260
261
261
262
const ReactCurrentOwner = ReactSharedInternals . ReactCurrentOwner ;
@@ -655,13 +656,14 @@ function updateOffscreenComponent(
655
656
const nextState : OffscreenState = {
656
657
baseLanes : NoLanes ,
657
658
cachePool : null ,
659
+ transitions : null ,
658
660
} ;
659
661
workInProgress . memoizedState = nextState ;
660
662
if ( enableCache ) {
661
663
// push the cache pool even though we're going to bail out
662
664
// because otherwise there'd be a context mismatch
663
665
if ( current !== null ) {
664
- pushTransition ( workInProgress , null ) ;
666
+ pushTransition ( workInProgress , null , null ) ;
665
667
}
666
668
}
667
669
pushRenderLanes ( workInProgress , renderLanes ) ;
@@ -688,14 +690,15 @@ function updateOffscreenComponent(
688
690
const nextState : OffscreenState = {
689
691
baseLanes : nextBaseLanes ,
690
692
cachePool : spawnedCachePool ,
693
+ transitions : null ,
691
694
} ;
692
695
workInProgress . memoizedState = nextState ;
693
696
workInProgress . updateQueue = null ;
694
697
if ( enableCache ) {
695
698
// push the cache pool even though we're going to bail out
696
699
// because otherwise there'd be a context mismatch
697
700
if ( current !== null ) {
698
- pushTransition ( workInProgress , null ) ;
701
+ pushTransition ( workInProgress , null , null ) ;
699
702
}
700
703
}
701
704
@@ -723,6 +726,7 @@ function updateOffscreenComponent(
723
726
const nextState : OffscreenState = {
724
727
baseLanes : NoLanes ,
725
728
cachePool : null ,
729
+ transitions : null ,
726
730
} ;
727
731
workInProgress . memoizedState = nextState ;
728
732
// Push the lanes that were skipped when we bailed out.
@@ -733,7 +737,7 @@ function updateOffscreenComponent(
733
737
// using the same cache. Unless the parent changed, since that means
734
738
// there was a refresh.
735
739
const prevCachePool = prevState !== null ? prevState . cachePool : null ;
736
- pushTransition ( workInProgress , prevCachePool ) ;
740
+ pushTransition ( workInProgress , prevCachePool , null ) ;
737
741
}
738
742
739
743
pushRenderLanes ( workInProgress , subtreeRenderLanes ) ;
@@ -746,14 +750,14 @@ function updateOffscreenComponent(
746
750
747
751
subtreeRenderLanes = mergeLanes ( prevState . baseLanes , renderLanes ) ;
748
752
749
- if ( enableCache ) {
753
+ if ( enableCache || enableTransitionTracing ) {
750
754
// If the render that spawned this one accessed the cache pool, resume
751
755
// using the same cache. Unless the parent changed, since that means
752
756
// there was a refresh.
753
757
const prevCachePool = prevState . cachePool ;
754
- pushTransition ( workInProgress , prevCachePool ) ;
758
+ const transitions = prevState . transitions ;
759
+ pushTransition ( workInProgress , prevCachePool , transitions ) ;
755
760
}
756
-
757
761
// Since we're not hidden anymore, reset the state
758
762
workInProgress . memoizedState = null ;
759
763
} else {
@@ -767,7 +771,7 @@ function updateOffscreenComponent(
767
771
// using the same cache. Unless the parent changed, since that means
768
772
// there was a refresh.
769
773
if ( current !== null ) {
770
- pushTransition ( workInProgress , null ) ;
774
+ pushTransition ( workInProgress , null , null ) ;
771
775
}
772
776
}
773
777
}
@@ -1325,27 +1329,34 @@ function updateHostRoot(current, workInProgress, renderLanes) {
1325
1329
const nextProps = workInProgress . pendingProps ;
1326
1330
const prevState = workInProgress . memoizedState ;
1327
1331
const prevChildren = prevState . element ;
1332
+
1328
1333
cloneUpdateQueue ( current , workInProgress ) ;
1329
1334
processUpdateQueue ( workInProgress , nextProps , null , renderLanes ) ;
1330
1335
1331
1336
const nextState : RootState = workInProgress . memoizedState ;
1332
1337
const root : FiberRoot = workInProgress . stateNode ;
1333
1338
1339
+ if ( enableCache || enableTransitionTracing ) {
1340
+ pushRootTransition ( workInProgress , root , renderLanes ) ;
1341
+ }
1342
+
1334
1343
if ( enableCache ) {
1335
- const nextCache : Cache = nextState . cache ;
1336
- pushRootTransition ( root ) ;
1344
+ const nextCache : Cache = workInProgress . memoizedState . cache ;
1337
1345
pushCacheProvider ( workInProgress , nextCache ) ;
1338
1346
if ( nextCache !== prevState . cache ) {
1339
1347
// The root cache refreshed.
1340
1348
propagateContextChange ( workInProgress , CacheContext , renderLanes ) ;
1341
1349
}
1342
1350
}
1343
1351
1352
+ let pendingSuspenseBoundaries = nextState . pendingSuspenseBoundaries ;
1344
1353
if ( enableTransitionTracing ) {
1345
- // FIXME: Slipped past code review. This is not a safe mutation:
1346
- // workInProgress.memoizedState is a shared object. Need to fix before
1347
- // rolling out the Transition Tracing experiment.
1348
- workInProgress . memoizedState . transitions = getWorkInProgressTransitions ( ) ;
1354
+ if ( prevState . pendingSuspenseBoundaries === null ) {
1355
+ pendingSuspenseBoundaries = new Map ( ) ;
1356
+ }
1357
+ // TODO(luna) change to pushPendingSuspenseBoundaries
1358
+ // once we add tracing markers
1359
+ setRootPendingSuspenseBoundaries ( pendingSuspenseBoundaries ) ;
1349
1360
}
1350
1361
1351
1362
// Caution: React DevTools currently depends on this property
@@ -1361,6 +1372,7 @@ function updateHostRoot(current, workInProgress, renderLanes) {
1361
1372
element : nextChildren ,
1362
1373
isDehydrated : false ,
1363
1374
cache : nextState . cache ,
1375
+ pendingSuspenseBoundaries : pendingSuspenseBoundaries ,
1364
1376
transitions : nextState . transitions ,
1365
1377
} ;
1366
1378
const updateQueue : UpdateQueue < RootState > = (workInProgress.updateQueue: any);
@@ -1434,6 +1446,20 @@ function updateHostRoot(current, workInProgress, renderLanes) {
1434
1446
}
1435
1447
}
1436
1448
} else {
1449
+ if ( enableTransitionTracing ) {
1450
+ if ( pendingSuspenseBoundaries !== nextState . pendingSuspenseBoundaries ) {
1451
+ const overrideState : RootState = {
1452
+ element : nextChildren ,
1453
+ isDehydrated : nextState . isDehydrated ,
1454
+ cache : nextState . cache ,
1455
+ pendingSuspenseBoundaries : pendingSuspenseBoundaries ,
1456
+ transitions : nextState . transitions ,
1457
+ } ;
1458
+
1459
+ workInProgress . memoizedState = overrideState ;
1460
+ }
1461
+ }
1462
+
1437
1463
// Root is not dehydrated. Either this is a client-only root, or it
1438
1464
// already hydrated.
1439
1465
resetHydrationState ( ) ;
@@ -1978,6 +2004,7 @@ function mountSuspenseOffscreenState(renderLanes: Lanes): OffscreenState {
1978
2004
return {
1979
2005
baseLanes : renderLanes ,
1980
2006
cachePool : getSuspendedCache ( ) ,
2007
+ transitions : getSuspendedTransitions ( ) ,
1981
2008
} ;
1982
2009
}
1983
2010
@@ -2009,9 +2036,22 @@ function updateSuspenseOffscreenState(
2009
2036
cachePool = getSuspendedCache ( ) ;
2010
2037
}
2011
2038
}
2039
+
2040
+ let transitions = null ;
2041
+ if ( enableTransitionTracing ) {
2042
+ const currentTransitions = getSuspendedTransitions ( ) ;
2043
+ const prevTransitions = prevOffscreenState . transitions ;
2044
+ if ( prevTransitions !== null ) {
2045
+ transitions = prevTransitions . concat ( currentTransitions ) ;
2046
+ } else {
2047
+ transitions = currentTransitions ;
2048
+ }
2049
+ }
2050
+
2012
2051
return {
2013
2052
baseLanes : mergeLanes ( prevOffscreenState . baseLanes , renderLanes ) ,
2014
2053
cachePool,
2054
+ transitions,
2015
2055
} ;
2016
2056
}
2017
2057
@@ -2345,6 +2385,7 @@ function mountSuspensePrimaryChildren(
2345
2385
renderLanes ,
2346
2386
) {
2347
2387
const mode = workInProgress . mode ;
2388
+
2348
2389
const primaryChildProps : OffscreenProps = {
2349
2390
mode : 'visible' ,
2350
2391
children : primaryChildren ,
@@ -2367,7 +2408,6 @@ function mountSuspenseFallbackChildren(
2367
2408
) {
2368
2409
const mode = workInProgress . mode ;
2369
2410
const progressedPrimaryFragment : Fiber | null = workInProgress . child ;
2370
-
2371
2411
const primaryChildProps : OffscreenProps = {
2372
2412
mode : 'hidden' ,
2373
2413
children : primaryChildren ,
@@ -3571,14 +3611,25 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
3571
3611
case HostRoot :
3572
3612
pushHostRootContext ( workInProgress ) ;
3573
3613
const root : FiberRoot = workInProgress . stateNode ;
3614
+ if ( enableCache || enableTransitionTracing ) {
3615
+ pushRootTransition ( workInProgress , root , renderLanes ) ;
3616
+ }
3617
+
3574
3618
if ( enableCache ) {
3575
3619
const cache : Cache = current . memoizedState . cache ;
3576
3620
pushCacheProvider ( workInProgress , cache ) ;
3577
- pushRootTransition ( root ) ;
3578
3621
}
3622
+
3579
3623
if ( enableTransitionTracing ) {
3580
- workInProgress . memoizedState . transitions = getWorkInProgressTransitions ( ) ;
3624
+ const pendingSuspenseBoundaries =
3625
+ workInProgress . memoizedState . pendingSuspenseBoundaries ;
3626
+ // TODO(luna) change to pushPendingSuspenseBoundaries
3627
+ // once we add tracing markers
3628
+ if ( pendingSuspenseBoundaries ) {
3629
+ setRootPendingSuspenseBoundaries ( pendingSuspenseBoundaries ) ;
3630
+ }
3581
3631
}
3632
+
3582
3633
resetHydrationState ( ) ;
3583
3634
break ;
3584
3635
case HostComponent :
0 commit comments