@@ -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,27 +1329,34 @@ 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 ) ;
13301335
13311336 const nextState : RootState = workInProgress . memoizedState ;
13321337 const root : FiberRoot = workInProgress . stateNode ;
13331338
1339+ if ( enableCache || enableTransitionTracing ) {
1340+ pushRootTransition ( workInProgress , root , renderLanes ) ;
1341+ }
1342+
13341343 if ( enableCache ) {
1335- const nextCache : Cache = nextState . cache ;
1336- pushRootTransition ( root ) ;
1344+ const nextCache : Cache = workInProgress . memoizedState . cache ;
13371345 pushCacheProvider ( workInProgress , nextCache ) ;
13381346 if ( nextCache !== prevState . cache ) {
13391347 // The root cache refreshed.
13401348 propagateContextChange ( workInProgress , CacheContext , renderLanes ) ;
13411349 }
13421350 }
13431351
1352+ let pendingSuspenseBoundaries = nextState . pendingSuspenseBoundaries ;
13441353 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 ) ;
13491360 }
13501361
13511362 // Caution: React DevTools currently depends on this property
@@ -1361,6 +1372,7 @@ function updateHostRoot(current, workInProgress, renderLanes) {
13611372 element : nextChildren ,
13621373 isDehydrated : false ,
13631374 cache : nextState . cache ,
1375+ pendingSuspenseBoundaries : pendingSuspenseBoundaries ,
13641376 transitions : nextState . transitions ,
13651377 } ;
13661378 const updateQueue : UpdateQueue < RootState > = (workInProgress.updateQueue: any);
@@ -1434,6 +1446,20 @@ function updateHostRoot(current, workInProgress, renderLanes) {
14341446 }
14351447 }
14361448 } 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+
14371463 // Root is not dehydrated. Either this is a client-only root, or it
14381464 // already hydrated.
14391465 resetHydrationState ( ) ;
@@ -1978,6 +2004,7 @@ function mountSuspenseOffscreenState(renderLanes: Lanes): OffscreenState {
19782004 return {
19792005 baseLanes : renderLanes ,
19802006 cachePool : getSuspendedCache ( ) ,
2007+ transitions : getSuspendedTransitions ( ) ,
19812008 } ;
19822009}
19832010
@@ -2009,9 +2036,22 @@ function updateSuspenseOffscreenState(
20092036 cachePool = getSuspendedCache ( ) ;
20102037 }
20112038 }
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+
20122051 return {
20132052 baseLanes : mergeLanes ( prevOffscreenState . baseLanes , renderLanes ) ,
20142053 cachePool,
2054+ transitions,
20152055 } ;
20162056}
20172057
@@ -2345,6 +2385,7 @@ function mountSuspensePrimaryChildren(
23452385 renderLanes ,
23462386) {
23472387 const mode = workInProgress . mode ;
2388+
23482389 const primaryChildProps : OffscreenProps = {
23492390 mode : 'visible' ,
23502391 children : primaryChildren ,
@@ -2367,7 +2408,6 @@ function mountSuspenseFallbackChildren(
23672408) {
23682409 const mode = workInProgress . mode ;
23692410 const progressedPrimaryFragment : Fiber | null = workInProgress . child ;
2370-
23712411 const primaryChildProps : OffscreenProps = {
23722412 mode : 'hidden' ,
23732413 children : primaryChildren ,
@@ -3571,14 +3611,25 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
35713611 case HostRoot :
35723612 pushHostRootContext ( workInProgress ) ;
35733613 const root : FiberRoot = workInProgress . stateNode ;
3614+ if ( enableCache || enableTransitionTracing ) {
3615+ pushRootTransition ( workInProgress , root , renderLanes ) ;
3616+ }
3617+
35743618 if ( enableCache ) {
35753619 const cache : Cache = current . memoizedState . cache ;
35763620 pushCacheProvider ( workInProgress , cache ) ;
3577- pushRootTransition ( root ) ;
35783621 }
3622+
35793623 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+ }
35813631 }
3632+
35823633 resetHydrationState ( ) ;
35833634 break ;
35843635 case HostComponent :
0 commit comments