@@ -11,6 +11,25 @@ import type {FiberRoot} from './ReactInternalTypes';
11
11
12
12
// TODO: Ideally these types would be opaque but that doesn't work well with
13
13
// 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 ;
14
33
15
34
export type Lanes = number ;
16
35
export type Lane = number ;
@@ -24,6 +43,28 @@ import {
24
43
} from 'shared/ReactFeatureFlags' ;
25
44
import { isDevToolsPresent } from './ReactFiberDevToolsHook.new' ;
26
45
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
+
27
68
// Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler.
28
69
// If those values are changed that package should be rebuilt and redeployed.
29
70
@@ -127,19 +168,29 @@ export const NoTimestamp = -1;
127
168
let nextTransitionLane : Lane = TransitionLane1 ;
128
169
let nextRetryLane : Lane = RetryLane1 ;
129
170
171
+ // "Registers" used to "return" multiple values
172
+ // Used by getHighestPriorityLanes and getNextLanes:
173
+ let return_highestLanePriority : LanePriority = DefaultLanePriority ;
174
+
130
175
function getHighestPriorityLanes ( lanes : Lanes | Lane ) : Lanes {
131
176
switch ( getHighestPriorityLane ( lanes ) ) {
132
177
case SyncLane:
178
+ return_highestLanePriority = SyncLanePriority ;
133
179
return SyncLane ;
134
180
case InputContinuousHydrationLane:
181
+ return_highestLanePriority = InputContinuousHydrationLanePriority ;
135
182
return InputContinuousHydrationLane ;
136
183
case InputContinuousLane:
184
+ return_highestLanePriority = InputContinuousLanePriority ;
137
185
return InputContinuousLane ;
138
186
case DefaultHydrationLane:
187
+ return_highestLanePriority = DefaultHydrationLanePriority ;
139
188
return DefaultHydrationLane ;
140
189
case DefaultLane:
190
+ return_highestLanePriority = DefaultLanePriority ;
141
191
return DefaultLane ;
142
192
case TransitionHydrationLane:
193
+ return_highestLanePriority = TransitionHydrationPriority ;
143
194
return TransitionHydrationLane ;
144
195
case TransitionLane1:
145
196
case TransitionLane2:
@@ -157,20 +208,26 @@ function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
157
208
case TransitionLane14:
158
209
case TransitionLane15:
159
210
case TransitionLane16:
211
+ return_highestLanePriority = TransitionPriority ;
160
212
return lanes & TransitionLanes ;
161
213
case RetryLane1 :
162
214
case RetryLane2:
163
215
case RetryLane3:
164
216
case RetryLane4:
165
217
case RetryLane5:
218
+ return_highestLanePriority = RetryLanePriority ;
166
219
return lanes & RetryLanes ;
167
220
case SelectiveHydrationLane:
221
+ return_highestLanePriority = SelectiveHydrationLanePriority ;
168
222
return SelectiveHydrationLane ;
169
223
case IdleHydrationLane:
224
+ return_highestLanePriority = IdleHydrationLanePriority ;
170
225
return IdleHydrationLane ;
171
226
case IdleLane :
227
+ return_highestLanePriority = IdleLanePriority ;
172
228
return IdleLane ;
173
229
case OffscreenLane:
230
+ return_highestLanePriority = OffscreenLanePriority ;
174
231
return OffscreenLane ;
175
232
default:
176
233
if ( __DEV__ ) {
@@ -179,6 +236,7 @@ function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
179
236
) ;
180
237
}
181
238
// This shouldn't be reachable, but as a fallback, return the entire bitmask.
239
+ return_highestLanePriority = DefaultLanePriority ;
182
240
return lanes ;
183
241
}
184
242
}
@@ -187,10 +245,12 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
187
245
// Early bailout if there's no pending work left.
188
246
const pendingLanes = root . pendingLanes ;
189
247
if ( pendingLanes === NoLanes ) {
248
+ return_highestLanePriority = NoLanePriority ;
190
249
return NoLanes ;
191
250
}
192
251
193
252
let nextLanes = NoLanes ;
253
+ let nextLanePriority = NoLanePriority ;
194
254
195
255
const suspendedLanes = root . suspendedLanes ;
196
256
const pingedLanes = root . pingedLanes ;
@@ -202,20 +262,24 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
202
262
const nonIdleUnblockedLanes = nonIdlePendingLanes & ~ suspendedLanes ;
203
263
if ( nonIdleUnblockedLanes !== NoLanes ) {
204
264
nextLanes = getHighestPriorityLanes ( nonIdleUnblockedLanes ) ;
265
+ nextLanePriority = return_highestLanePriority ;
205
266
} else {
206
267
const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes ;
207
268
if ( nonIdlePingedLanes !== NoLanes ) {
208
269
nextLanes = getHighestPriorityLanes ( nonIdlePingedLanes ) ;
270
+ nextLanePriority = return_highestLanePriority ;
209
271
}
210
272
}
211
273
} else {
212
274
// The only remaining work is Idle.
213
275
const unblockedLanes = pendingLanes & ~ suspendedLanes ;
214
276
if ( unblockedLanes !== NoLanes ) {
215
277
nextLanes = getHighestPriorityLanes ( unblockedLanes ) ;
278
+ nextLanePriority = return_highestLanePriority ;
216
279
} else {
217
280
if ( pingedLanes !== NoLanes ) {
218
281
nextLanes = getHighestPriorityLanes ( pingedLanes ) ;
282
+ nextLanePriority = return_highestLanePriority ;
219
283
}
220
284
}
221
285
}
@@ -249,6 +313,8 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
249
313
) {
250
314
// Keep working on the existing in-progress tree. Do not interrupt.
251
315
return wipLanes ;
316
+ } else {
317
+ return_highestLanePriority = nextLanePriority ;
252
318
}
253
319
}
254
320
@@ -443,6 +509,9 @@ export function getLanesToRetrySynchronouslyOnError(root: FiberRoot): Lanes {
443
509
return NoLanes ;
444
510
}
445
511
512
+ export function returnNextLanesPriority ( ) {
513
+ return return_highestLanePriority ;
514
+ }
446
515
export function includesNonIdleWork ( lanes : Lanes ) {
447
516
return ( lanes & NonIdleLanes ) !== NoLanes ;
448
517
}
@@ -548,6 +617,13 @@ export function higherPriorityLane(a: Lane, b: Lane) {
548
617
return a !== NoLane && a < b ? a : b ;
549
618
}
550
619
620
+ export function higherLanePriority (
621
+ a : LanePriority ,
622
+ b : LanePriority ,
623
+ ) : LanePriority {
624
+ return a !== NoLanePriority && a > b ? a : b ;
625
+ }
626
+
551
627
export function createLaneMap < T > (initial: T): LaneMap< T > {
552
628
// Intentionally pushing one by one.
553
629
// https://v8.dev/blog/elements-kinds#avoid-creating-holes
0 commit comments