@@ -11,6 +11,25 @@ import type {FiberRoot} from './ReactInternalTypes';
1111
1212// TODO: Ideally these types would be opaque but that doesn't work well with
1313// our reconciler fork infra, since these leak into non-reconciler packages.
14+ export type LanePriority =
15+ | 0
16+ | 1
17+ | 2
18+ | 3
19+ | 4
20+ | 5
21+ | 6
22+ | 7
23+ | 8
24+ | 9
25+ | 10
26+ | 11
27+ | 12
28+ | 13
29+ | 14
30+ | 15
31+ | 16
32+ | 17 ;
1433
1534export type Lanes = number ;
1635export type Lane = number ;
@@ -24,6 +43,28 @@ import {
2443} from 'shared/ReactFeatureFlags' ;
2544import { isDevToolsPresent } from './ReactFiberDevToolsHook.new' ;
2645
46+ export const SyncLanePriority : LanePriority = 12 ;
47+
48+ const InputContinuousHydrationLanePriority : LanePriority = 11 ;
49+ export const InputContinuousLanePriority : LanePriority = 10 ;
50+
51+ const DefaultHydrationLanePriority : LanePriority = 9 ;
52+ export const DefaultLanePriority : LanePriority = 8 ;
53+
54+ const TransitionHydrationPriority : LanePriority = 7 ;
55+ export const TransitionPriority : LanePriority = 6 ;
56+
57+ const RetryLanePriority : LanePriority = 5 ;
58+
59+ const SelectiveHydrationLanePriority : LanePriority = 4 ;
60+
61+ const IdleHydrationLanePriority : LanePriority = 3 ;
62+ export const IdleLanePriority : LanePriority = 2 ;
63+
64+ const OffscreenLanePriority : LanePriority = 1 ;
65+
66+ export const NoLanePriority : LanePriority = 0 ;
67+
2768// Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler.
2869// If those values are changed that package should be rebuilt and redeployed.
2970
@@ -127,19 +168,29 @@ export const NoTimestamp = -1;
127168let nextTransitionLane : Lane = TransitionLane1 ;
128169let nextRetryLane : Lane = RetryLane1 ;
129170
171+ // "Registers" used to "return" multiple values
172+ // Used by getHighestPriorityLanes and getNextLanes:
173+ let return_highestLanePriority : LanePriority = DefaultLanePriority ;
174+
130175function getHighestPriorityLanes ( lanes : Lanes | Lane ) : Lanes {
131176 switch ( getHighestPriorityLane ( lanes ) ) {
132177 case SyncLane:
178+ return_highestLanePriority = SyncLanePriority ;
133179 return SyncLane ;
134180 case InputContinuousHydrationLane:
181+ return_highestLanePriority = InputContinuousHydrationLanePriority ;
135182 return InputContinuousHydrationLane ;
136183 case InputContinuousLane:
184+ return_highestLanePriority = InputContinuousLanePriority ;
137185 return InputContinuousLane ;
138186 case DefaultHydrationLane:
187+ return_highestLanePriority = DefaultHydrationLanePriority ;
139188 return DefaultHydrationLane ;
140189 case DefaultLane:
190+ return_highestLanePriority = DefaultLanePriority ;
141191 return DefaultLane ;
142192 case TransitionHydrationLane:
193+ return_highestLanePriority = TransitionHydrationPriority ;
143194 return TransitionHydrationLane ;
144195 case TransitionLane1:
145196 case TransitionLane2:
@@ -157,20 +208,26 @@ function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
157208 case TransitionLane14:
158209 case TransitionLane15:
159210 case TransitionLane16:
211+ return_highestLanePriority = TransitionPriority ;
160212 return lanes & TransitionLanes ;
161213 case RetryLane1 :
162214 case RetryLane2:
163215 case RetryLane3:
164216 case RetryLane4:
165217 case RetryLane5:
218+ return_highestLanePriority = RetryLanePriority ;
166219 return lanes & RetryLanes ;
167220 case SelectiveHydrationLane:
221+ return_highestLanePriority = SelectiveHydrationLanePriority ;
168222 return SelectiveHydrationLane ;
169223 case IdleHydrationLane:
224+ return_highestLanePriority = IdleHydrationLanePriority ;
170225 return IdleHydrationLane ;
171226 case IdleLane :
227+ return_highestLanePriority = IdleLanePriority ;
172228 return IdleLane ;
173229 case OffscreenLane:
230+ return_highestLanePriority = OffscreenLanePriority ;
174231 return OffscreenLane ;
175232 default:
176233 if ( __DEV__ ) {
@@ -179,6 +236,7 @@ function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
179236 ) ;
180237 }
181238 // This shouldn't be reachable, but as a fallback, return the entire bitmask.
239+ return_highestLanePriority = DefaultLanePriority ;
182240 return lanes ;
183241 }
184242}
@@ -187,10 +245,12 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
187245 // Early bailout if there's no pending work left.
188246 const pendingLanes = root . pendingLanes ;
189247 if ( pendingLanes === NoLanes ) {
248+ return_highestLanePriority = NoLanePriority ;
190249 return NoLanes ;
191250 }
192251
193252 let nextLanes = NoLanes ;
253+ let nextLanePriority = NoLanePriority ;
194254
195255 const suspendedLanes = root . suspendedLanes ;
196256 const pingedLanes = root . pingedLanes ;
@@ -202,20 +262,24 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
202262 const nonIdleUnblockedLanes = nonIdlePendingLanes & ~ suspendedLanes ;
203263 if ( nonIdleUnblockedLanes !== NoLanes ) {
204264 nextLanes = getHighestPriorityLanes ( nonIdleUnblockedLanes ) ;
265+ nextLanePriority = return_highestLanePriority ;
205266 } else {
206267 const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes ;
207268 if ( nonIdlePingedLanes !== NoLanes ) {
208269 nextLanes = getHighestPriorityLanes ( nonIdlePingedLanes ) ;
270+ nextLanePriority = return_highestLanePriority ;
209271 }
210272 }
211273 } else {
212274 // The only remaining work is Idle.
213275 const unblockedLanes = pendingLanes & ~ suspendedLanes ;
214276 if ( unblockedLanes !== NoLanes ) {
215277 nextLanes = getHighestPriorityLanes ( unblockedLanes ) ;
278+ nextLanePriority = return_highestLanePriority ;
216279 } else {
217280 if ( pingedLanes !== NoLanes ) {
218281 nextLanes = getHighestPriorityLanes ( pingedLanes ) ;
282+ nextLanePriority = return_highestLanePriority ;
219283 }
220284 }
221285 }
@@ -249,6 +313,8 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
249313 ) {
250314 // Keep working on the existing in-progress tree. Do not interrupt.
251315 return wipLanes ;
316+ } else {
317+ return_highestLanePriority = nextLanePriority ;
252318 }
253319 }
254320
@@ -443,6 +509,9 @@ export function getLanesToRetrySynchronouslyOnError(root: FiberRoot): Lanes {
443509 return NoLanes ;
444510}
445511
512+ export function returnNextLanesPriority ( ) {
513+ return return_highestLanePriority ;
514+ }
446515export function includesNonIdleWork ( lanes : Lanes ) {
447516 return ( lanes & NonIdleLanes ) !== NoLanes ;
448517}
@@ -548,6 +617,13 @@ export function higherPriorityLane(a: Lane, b: Lane) {
548617 return a !== NoLane && a < b ? a : b ;
549618}
550619
620+ export function higherLanePriority (
621+ a : LanePriority ,
622+ b : LanePriority ,
623+ ) : LanePriority {
624+ return a !== NoLanePriority && a > b ? a : b ;
625+ }
626+
551627export function createLaneMap < T > (initial: T): LaneMap< T > {
552628 // Intentionally pushing one by one.
553629 // https://v8.dev/blog/elements-kinds#avoid-creating-holes
0 commit comments