@@ -14,6 +14,7 @@ import type {TimeoutHandle, NoTimeout} from './ReactFiberHostConfig';
1414import  type  { Thenable }  from  './ReactFiberWorkLoop' ; 
1515import  type  { Interaction }  from  'scheduler/src/Tracing' ; 
1616import  type  { SuspenseHydrationCallbacks }  from  './ReactFiberSuspenseComponent' ; 
17+ import  type  { ReactPriorityLevel }  from  './SchedulerWithReactIntegration' ; 
1718
1819import  { noTimeout }  from  './ReactFiberHostConfig' ; 
1920import  { createHostRootFiber }  from  './ReactFiber' ; 
@@ -23,6 +24,7 @@ import {
2324  enableSuspenseCallback , 
2425}  from  'shared/ReactFeatureFlags' ; 
2526import  { unstable_getThreadID }  from  'scheduler/tracing' ; 
27+ import  { NoPriority }  from  './SchedulerWithReactIntegration' ; 
2628
2729// TODO: This should be lifted into the renderer. 
2830export  type  Batch  =  { 
@@ -69,6 +71,8 @@ type BaseFiberRootProperties = {|
6971  callbackNode : * , 
7072  // Expiration of the callback associated with this root 
7173  callbackExpirationTime : ExpirationTime , 
74+   // Priority of the callback associated with this root 
75+   callbackPriority : ReactPriorityLevel , 
7276  // The earliest pending expiration time that exists in the tree 
7377  firstPendingTime : ExpirationTime , 
7478  // The latest pending expiration time that exists in the tree 
@@ -78,7 +82,7 @@ type BaseFiberRootProperties = {|
7882  // The latest suspended expiration time that exists in the tree 
7983  lastSuspendedTime : ExpirationTime , 
8084  // The next known expiration time after the suspended range 
81-   nextAfterSuspendedTime : ExpirationTime , 
85+   nextKnownPendingLevel : ExpirationTime , 
8286  // The latest time at which a suspended component pinged the root to 
8387  // render again 
8488  lastPingedTime : ExpirationTime , 
@@ -124,12 +128,12 @@ function FiberRootNode(containerInfo, tag, hydrate) {
124128  this . hydrate  =  hydrate ; 
125129  this . firstBatch  =  null ; 
126130  this . callbackNode  =  null ; 
127-   this . callbackExpirationTime  =  NoWork ; 
131+   this . callbackPriority  =  NoPriority ; 
128132  this . firstPendingTime  =  NoWork ; 
129133  this . lastPendingTime  =  NoWork ; 
130134  this . firstSuspendedTime  =  NoWork ; 
131135  this . lastSuspendedTime  =  NoWork ; 
132-   this . nextAfterSuspendedTime  =  NoWork ; 
136+   this . nextKnownPendingLevel  =  NoWork ; 
133137  this . lastPingedTime  =  NoWork ; 
134138
135139  if  ( enableSchedulerTracing )  { 
@@ -193,21 +197,66 @@ export function markRootSuspendedAtTime(
193197  } 
194198} 
195199
196- export  function  markRootUnsuspendedAtTime ( 
200+ export  function  markRootUpdatedAtTime ( 
197201  root : FiberRoot , 
198202  expirationTime : ExpirationTime , 
199203) : void  { 
200-   if  ( expirationTime  <=  root . lastSuspendedTime )  { 
204+   // Update the range of pending times 
205+   const  firstPendingTime =  root . firstPendingTime ; 
206+   if  ( expirationTime  >  firstPendingTime )  { 
207+     root . firstPendingTime  =  expirationTime ; 
208+   } 
209+   const  lastPendingTime  =  root . lastPendingTime ; 
210+   if  ( lastPendingTime  ===  NoWork  ||  expirationTime  <  lastPendingTime )  { 
211+     root . lastPendingTime  =  expirationTime ; 
212+   } 
213+ 
214+   // Update the range of suspended times. Treat everything lower priority or 
215+   // equal to this update as unsuspended. 
216+   const  firstSuspendedTime  =  root . firstSuspendedTime ; 
217+   if  ( firstSuspendedTime  !==  NoWork )  { 
218+     if  ( expirationTime  >=  firstSuspendedTime )  { 
219+       // The entire suspended range is now unsuspended. 
220+       root . firstSuspendedTime  =  root . lastSuspendedTime  =  root . nextKnownPendingLevel  =  NoWork ; 
221+     }  else  if  ( expirationTime  >=  root . lastSuspendedTime )  { 
222+       root . lastSuspendedTime  =  expirationTime  +  1 ; 
223+     } 
224+ 
225+     // This is a pending level. Check if it's higher priority than the next 
226+     // known pending level. 
227+     if  ( expirationTime  >  root . nextKnownPendingLevel )  { 
228+       root . nextKnownPendingLevel  =  expirationTime ; 
229+     } 
230+   } 
231+ } 
232+ 
233+ export  function  markRootFinishedAtTime ( 
234+   root : FiberRoot , 
235+   finishedExpirationTime : ExpirationTime , 
236+   remainingExpirationTime : ExpirationTime , 
237+ ) : void  { 
238+   // Update the range of pending times 
239+   root. firstPendingTime  =  remainingExpirationTime ; 
240+   if  ( remainingExpirationTime  <  root . lastPendingTime )  { 
241+     // This usually means we've finished all the work, but it can also happen 
242+     // when something gets downprioritized during render, like a hidden tree. 
243+     root . lastPendingTime  =  remainingExpirationTime ; 
244+   } 
245+ 
246+   // Update the range of suspended times. Treat everything higher priority or 
247+   // equal to this update as unsuspended. 
248+   if  ( finishedExpirationTime  <=  root . lastSuspendedTime )  { 
201249    // The entire suspended range is now unsuspended. 
202-     root . firstSuspendedTime  =  root . lastSuspendedTime  =  root . nextAfterSuspendedTime  =  NoWork ; 
203-   }  else  if  ( expirationTime  <=  root . firstSuspendedTime )  { 
250+     root . firstSuspendedTime  =  root . lastSuspendedTime  =  root . nextKnownPendingLevel  =  NoWork ; 
251+   }  else  if  ( finishedExpirationTime  <=  root . firstSuspendedTime )  { 
204252    // Part of the suspended range is now unsuspended. Narrow the range to 
205253    // include everything between the unsuspended time (non-inclusive) and the 
206254    // last suspended time. 
207-     root . firstSuspendedTime  =  expirationTime  -  1 ; 
255+     root . firstSuspendedTime  =  finishedExpirationTime  -  1 ; 
208256  } 
209257
210-   if  ( expirationTime  <=  root . lastPingedTime )  { 
258+   if  ( finishedExpirationTime  <=  root . lastPingedTime )  { 
259+     // Clear the pinged time 
211260    root . lastPingedTime  =  NoWork ; 
212261  } 
213262} 
0 commit comments