@@ -236,7 +236,7 @@ import {
236236 markSkippedUpdateLanes ,
237237 getWorkInProgressRoot ,
238238 pushRenderLanes ,
239- getWorkInProgressTransitions ,
239+ setRootPendingSuspenseBoundaries ,
240240} from './ReactFiberWorkLoop.old' ;
241241import { setWorkInProgressVersion } from './ReactMutableSource.old' ;
242242import { pushCacheProvider , CacheContext } from './ReactFiberCacheComponent.old' ;
@@ -256,6 +256,7 @@ import {
256256 getSuspendedCache ,
257257 pushTransition ,
258258 getOffscreenDeferredCache ,
259+ getSuspendedTransitions ,
259260} from './ReactFiberTransition.old' ;
260261
261262const ReactCurrentOwner = ReactSharedInternals . ReactCurrentOwner ;
@@ -655,13 +656,14 @@ function updateOffscreenComponent(
655656 const nextState : OffscreenState = {
656657 baseLanes : NoLanes ,
657658 cachePool : null ,
659+ transitions : null ,
658660 } ;
659661 workInProgress . memoizedState = nextState ;
660662 if ( enableCache ) {
661663 // push the cache pool even though we're going to bail out
662664 // because otherwise there'd be a context mismatch
663665 if ( current !== null ) {
664- pushTransition ( workInProgress , null ) ;
666+ pushTransition ( workInProgress , null , null ) ;
665667 }
666668 }
667669 pushRenderLanes ( workInProgress , renderLanes ) ;
@@ -688,14 +690,15 @@ function updateOffscreenComponent(
688690 const nextState : OffscreenState = {
689691 baseLanes : nextBaseLanes ,
690692 cachePool : spawnedCachePool ,
693+ transitions : null ,
691694 } ;
692695 workInProgress . memoizedState = nextState ;
693696 workInProgress . updateQueue = null ;
694697 if ( enableCache ) {
695698 // push the cache pool even though we're going to bail out
696699 // because otherwise there'd be a context mismatch
697700 if ( current !== null ) {
698- pushTransition ( workInProgress , null ) ;
701+ pushTransition ( workInProgress , null , null ) ;
699702 }
700703 }
701704
@@ -723,6 +726,7 @@ function updateOffscreenComponent(
723726 const nextState : OffscreenState = {
724727 baseLanes : NoLanes ,
725728 cachePool : null ,
729+ transitions : null ,
726730 } ;
727731 workInProgress . memoizedState = nextState ;
728732 // Push the lanes that were skipped when we bailed out.
@@ -733,7 +737,7 @@ function updateOffscreenComponent(
733737 // using the same cache. Unless the parent changed, since that means
734738 // there was a refresh.
735739 const prevCachePool = prevState !== null ? prevState . cachePool : null ;
736- pushTransition ( workInProgress , prevCachePool ) ;
740+ pushTransition ( workInProgress , prevCachePool , null ) ;
737741 }
738742
739743 pushRenderLanes ( workInProgress , subtreeRenderLanes ) ;
@@ -746,14 +750,14 @@ function updateOffscreenComponent(
746750
747751 subtreeRenderLanes = mergeLanes ( prevState . baseLanes , renderLanes ) ;
748752
749- if ( enableCache ) {
753+ if ( enableCache || enableTransitionTracing ) {
750754 // If the render that spawned this one accessed the cache pool, resume
751755 // using the same cache. Unless the parent changed, since that means
752756 // there was a refresh.
753757 const prevCachePool = prevState . cachePool ;
754- pushTransition ( workInProgress , prevCachePool ) ;
758+ const transitions = prevState . transitions ;
759+ pushTransition ( workInProgress , prevCachePool , transitions ) ;
755760 }
756-
757761 // Since we're not hidden anymore, reset the state
758762 workInProgress . memoizedState = null ;
759763 } else {
@@ -767,7 +771,7 @@ function updateOffscreenComponent(
767771 // using the same cache. Unless the parent changed, since that means
768772 // there was a refresh.
769773 if ( current !== null ) {
770- pushTransition ( workInProgress , null ) ;
774+ pushTransition ( workInProgress , null , null ) ;
771775 }
772776 }
773777 }
@@ -1325,29 +1329,57 @@ function updateHostRoot(current, workInProgress, renderLanes) {
13251329 const nextProps = workInProgress . pendingProps ;
13261330 const prevState = workInProgress . memoizedState ;
13271331 const prevChildren = prevState . element ;
1332+
13281333 cloneUpdateQueue ( current , workInProgress ) ;
13291334 processUpdateQueue ( workInProgress , nextProps , null , renderLanes ) ;
1330-
1331- const nextState : RootState = workInProgress . memoizedState ;
13321335 const root : FiberRoot = workInProgress . stateNode ;
13331336
1337+ if ( enableCache || enableTransitionTracing ) {
1338+ pushRootTransition ( workInProgress , root , renderLanes ) ;
1339+ }
1340+
13341341 if ( enableCache ) {
1335- const nextCache : Cache = nextState . cache ;
1336- pushRootTransition ( root ) ;
1342+ const nextCache : Cache = workInProgress . memoizedState . cache ;
13371343 pushCacheProvider ( workInProgress , nextCache ) ;
13381344 if ( nextCache !== prevState . cache ) {
13391345 // The root cache refreshed.
13401346 propagateContextChange ( workInProgress , CacheContext , renderLanes ) ;
13411347 }
13421348 }
13431349
1350+ let transitions = null ;
1351+ let pendingSuspenseBoundaries = null ;
13441352 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 ( ) ;
1353+ const currentTransitions = getSuspendedTransitions ( ) ;
1354+ const prevTransitions = prevState . transitions ;
1355+
1356+ if ( currentTransitions !== null ) {
1357+ if ( prevTransitions === null ) {
1358+ transitions = currentTransitions ;
1359+ } else {
1360+ transitions = prevTransitions . concat ( currentTransitions ) ;
1361+ }
1362+ } else {
1363+ transitions = prevTransitions ;
1364+ }
1365+
1366+ if ( prevState . pendingSuspenseBoundaries === null ) {
1367+ pendingSuspenseBoundaries = new Map ( ) ;
1368+ } else {
1369+ pendingSuspenseBoundaries = new Map ( prevState . pendingSuspenseBoundaries ) ;
1370+ }
1371+ setRootPendingSuspenseBoundaries ( pendingSuspenseBoundaries ) ;
13491372 }
13501373
1374+ const nextState : RootState = {
1375+ element : workInProgress . memoizedState . element ,
1376+ cache : workInProgress . memoizedState . cache ,
1377+ isDehydrated : workInProgress . memoizedState . isDehydrated ,
1378+ pendingSuspenseBoundaries,
1379+ transitions,
1380+ } ;
1381+ workInProgress . memoizedState = nextState ;
1382+
13511383 // Caution: React DevTools currently depends on this property
13521384 // being called "element".
13531385 const nextChildren = nextState . element ;
@@ -1361,6 +1393,7 @@ function updateHostRoot(current, workInProgress, renderLanes) {
13611393 element : nextChildren ,
13621394 isDehydrated : false ,
13631395 cache : nextState . cache ,
1396+ pendingSuspenseBoundaries : nextState . pendingSuspenseBoundaries ,
13641397 transitions : nextState . transitions ,
13651398 } ;
13661399 const updateQueue : UpdateQueue < RootState > = (workInProgress.updateQueue: any);
@@ -1978,6 +2011,7 @@ function mountSuspenseOffscreenState(renderLanes: Lanes): OffscreenState {
19782011 return {
19792012 baseLanes : renderLanes ,
19802013 cachePool : getSuspendedCache ( ) ,
2014+ transitions : getSuspendedTransitions ( ) ,
19812015 } ;
19822016}
19832017
@@ -2009,9 +2043,22 @@ function updateSuspenseOffscreenState(
20092043 cachePool = getSuspendedCache ( ) ;
20102044 }
20112045 }
2046+
2047+ let transitions = null ;
2048+ if ( enableTransitionTracing ) {
2049+ const currentTransitions = getSuspendedTransitions ( ) ;
2050+ const prevTransitions = prevOffscreenState . transitions ;
2051+ if ( prevTransitions !== null ) {
2052+ transitions = prevTransitions . concat ( currentTransitions ) ;
2053+ } else {
2054+ transitions = currentTransitions ;
2055+ }
2056+ }
2057+
20122058 return {
20132059 baseLanes : mergeLanes ( prevOffscreenState . baseLanes , renderLanes ) ,
20142060 cachePool,
2061+ transitions,
20152062 } ;
20162063}
20172064
@@ -2345,9 +2392,16 @@ function mountSuspensePrimaryChildren(
23452392 renderLanes ,
23462393) {
23472394 const mode = workInProgress . mode ;
2395+ const props = workInProgress . memoizedProps ;
2396+ let name = null ;
2397+ if ( props !== null ) {
2398+ name = props . name ;
2399+ }
2400+
23482401 const primaryChildProps : OffscreenProps = {
23492402 mode : 'visible' ,
23502403 children : primaryChildren ,
2404+ name,
23512405 } ;
23522406 const primaryChildFragment = mountWorkInProgressOffscreenFiber (
23532407 primaryChildProps ,
@@ -2367,10 +2421,15 @@ function mountSuspenseFallbackChildren(
23672421) {
23682422 const mode = workInProgress . mode ;
23692423 const progressedPrimaryFragment : Fiber | null = workInProgress . child ;
2370-
2424+ const props = workInProgress . memoizedProps ;
2425+ let name = null ;
2426+ if ( props !== null ) {
2427+ name = props . name ;
2428+ }
23712429 const primaryChildProps : OffscreenProps = {
23722430 mode : 'hidden' ,
23732431 children : primaryChildren ,
2432+ name,
23742433 } ;
23752434
23762435 let primaryChildFragment ;
@@ -2448,6 +2507,7 @@ function updateSuspensePrimaryChildren(
24482507 primaryChildren ,
24492508 renderLanes ,
24502509) {
2510+ const name = workInProgress . pendingProps . name ;
24512511 const currentPrimaryChildFragment : Fiber = ( current . child : any ) ;
24522512 const currentFallbackChildFragment : Fiber | null =
24532513 currentPrimaryChildFragment . sibling ;
@@ -2457,6 +2517,7 @@ function updateSuspensePrimaryChildren(
24572517 {
24582518 mode : 'visible' ,
24592519 children : primaryChildren ,
2520+ name,
24602521 } ,
24612522 ) ;
24622523 if ( ( workInProgress . mode & ConcurrentMode ) === NoMode ) {
@@ -2486,6 +2547,7 @@ function updateSuspenseFallbackChildren(
24862547 fallbackChildren ,
24872548 renderLanes ,
24882549) {
2550+ const name = workInProgress . pendingProps . name ;
24892551 const mode = workInProgress . mode ;
24902552 const currentPrimaryChildFragment : Fiber = ( current . child : any ) ;
24912553 const currentFallbackChildFragment : Fiber | null =
@@ -2494,6 +2556,7 @@ function updateSuspenseFallbackChildren(
24942556 const primaryChildProps : OffscreenProps = {
24952557 mode : 'hidden' ,
24962558 children : primaryChildren ,
2559+ name,
24972560 } ;
24982561
24992562 let primaryChildFragment ;
@@ -2652,10 +2715,12 @@ function mountSuspenseFallbackAfterRetryWithoutHydrating(
26522715 fallbackChildren ,
26532716 renderLanes ,
26542717) {
2718+ const name = workInProgress . pendingProps . name ;
26552719 const fiberMode = workInProgress . mode ;
26562720 const primaryChildProps : OffscreenProps = {
26572721 mode : 'visible' ,
26582722 children : primaryChildren ,
2723+ name,
26592724 } ;
26602725 const primaryChildFragment = mountWorkInProgressOffscreenFiber (
26612726 primaryChildProps ,
@@ -3571,14 +3636,50 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
35713636 case HostRoot :
35723637 pushHostRootContext ( workInProgress ) ;
35733638 const root : FiberRoot = workInProgress . stateNode ;
3639+ if ( enableCache || enableTransitionTracing ) {
3640+ pushRootTransition ( workInProgress , root , renderLanes ) ;
3641+ }
3642+
35743643 if ( enableCache ) {
35753644 const cache : Cache = current . memoizedState . cache ;
35763645 pushCacheProvider ( workInProgress , cache ) ;
3577- pushRootTransition ( root ) ;
35783646 }
3647+
3648+ let transitions = null ;
3649+ let pendingSuspenseBoundaries = null ;
35793650 if ( enableTransitionTracing ) {
3580- workInProgress . memoizedState . transitions = getWorkInProgressTransitions ( ) ;
3651+ const prevState = current . memoizedState ;
3652+
3653+ const currentTransitions = getSuspendedTransitions ( ) ;
3654+ const prevTransitions = prevState . transitions ;
3655+ if ( currentTransitions !== null ) {
3656+ if ( prevTransitions === null ) {
3657+ transitions = currentTransitions ;
3658+ } else {
3659+ transitions = prevTransitions . concat ( currentTransitions ) ;
3660+ }
3661+ } else {
3662+ transitions = prevTransitions ;
3663+ }
3664+
3665+ if ( prevState . pendingSuspenseBoundaries === null ) {
3666+ pendingSuspenseBoundaries = new Map ( ) ;
3667+ } else {
3668+ pendingSuspenseBoundaries = new Map (
3669+ prevState . pendingSuspenseBoundaries ,
3670+ ) ;
3671+ }
3672+ setRootPendingSuspenseBoundaries ( pendingSuspenseBoundaries ) ;
35813673 }
3674+
3675+ const nextState : RootState = {
3676+ element : workInProgress . memoizedState . element ,
3677+ cache : workInProgress . memoizedState . cache ,
3678+ isDehydrated : workInProgress . memoizedState . isDehydrated ,
3679+ pendingSuspenseBoundaries,
3680+ transitions,
3681+ } ;
3682+ workInProgress . memoizedState = nextState ;
35823683 resetHydrationState ( ) ;
35833684 break ;
35843685 case HostComponent :
0 commit comments