7
7
* @noflow
8
8
* @nolint
9
9
* @preventMunge
10
- * @generated SignedSource<<714756724eaa1bcdef36d80f02d51c1a >>
10
+ * @generated SignedSource<<5b025a45475b905abc64b47d27761956 >>
11
11
*/
12
12
13
13
'use strict';
@@ -1053,6 +1053,7 @@ var SyncHydrationLane =
1053
1053
var SyncLane =
1054
1054
/* */
1055
1055
2;
1056
+ var SyncLaneIndex = 1;
1056
1057
var InputContinuousHydrationLane =
1057
1058
/* */
1058
1059
4;
@@ -1297,13 +1298,18 @@ function getNextLanes(root, wipLanes) {
1297
1298
}
1298
1299
}
1299
1300
1301
+ return nextLanes;
1302
+ }
1303
+ function getEntangledLanes(root, renderLanes) {
1304
+ var entangledLanes = renderLanes;
1305
+
1300
1306
if ((root.current.mode & ConcurrentUpdatesByDefaultMode) !== NoMode);
1301
- else if ((nextLanes & InputContinuousLane) !== NoLanes) {
1307
+ else if ((entangledLanes & InputContinuousLane) !== NoLanes) {
1302
1308
// When updates are sync by default, we entangle continuous priority updates
1303
1309
// and default updates, so they render in the same batch. The only reason
1304
1310
// they use separate lanes is because continuous updates should interrupt
1305
1311
// transitions, but default updates should not.
1306
- nextLanes |= pendingLanes & DefaultLane;
1312
+ entangledLanes |= entangledLanes & DefaultLane;
1307
1313
} // Check for entangled lanes and add them to the batch.
1308
1314
//
1309
1315
// A lane is said to be entangled with another when it's not allowed to render
@@ -1327,21 +1333,21 @@ function getNextLanes(root, wipLanes) {
1327
1333
// we should ensure that there is no partial work at the
1328
1334
// time we apply the entanglement.
1329
1335
1330
- var entangledLanes = root.entangledLanes;
1336
+ var allEntangledLanes = root.entangledLanes;
1331
1337
1332
- if (entangledLanes !== NoLanes) {
1338
+ if (allEntangledLanes !== NoLanes) {
1333
1339
var entanglements = root.entanglements;
1334
- var lanes = nextLanes & entangledLanes ;
1340
+ var lanes = entangledLanes & allEntangledLanes ;
1335
1341
1336
1342
while (lanes > 0) {
1337
1343
var index = pickArbitraryLaneIndex(lanes);
1338
1344
var lane = 1 << index;
1339
- nextLanes |= entanglements[index];
1345
+ entangledLanes |= entanglements[index];
1340
1346
lanes &= ~lane;
1341
1347
}
1342
1348
}
1343
1349
1344
- return nextLanes ;
1350
+ return entangledLanes ;
1345
1351
}
1346
1352
1347
1353
function computeExpirationTime(lane, currentTime) {
@@ -1419,6 +1425,7 @@ function markStarvedLanesAsExpired(root, currentTime) {
1419
1425
var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
1420
1426
// expiration time. If so, we'll assume the update is being starved and mark
1421
1427
// it as expired to force it to finish.
1428
+ // TODO: We should be able to replace this with upgradePendingLanesToSync
1422
1429
//
1423
1430
// We exclude retry lanes because those must always be time sliced, in order
1424
1431
// to unwrap uncached promises.
@@ -1688,6 +1695,15 @@ function markRootEntangled(root, entangledLanes) {
1688
1695
lanes &= ~lane;
1689
1696
}
1690
1697
}
1698
+ function upgradePendingLaneToSync(root, lane) {
1699
+ // Since we're upgrading the priority of the given lane, there is now pending
1700
+ // sync work.
1701
+ root.pendingLanes |= SyncLane; // Entangle the sync lane with the lane we're upgrading. This means SyncLane
1702
+ // will not be allowed to finish without also finishing the given lane.
1703
+
1704
+ root.entangledLanes |= SyncLane;
1705
+ root.entanglements[SyncLaneIndex] |= lane;
1706
+ }
1691
1707
function markHiddenUpdate(root, update, lane) {
1692
1708
var index = laneToIndex(lane);
1693
1709
var hiddenUpdates = root.hiddenUpdates;
@@ -5813,22 +5829,24 @@ function resetChildFibers(workInProgress, lanes) {
5813
5829
// InvisibleParentContext that is currently managed by SuspenseContext.
5814
5830
5815
5831
var currentTreeHiddenStackCursor = createCursor(null);
5816
- var prevRenderLanesStackCursor = createCursor(NoLanes);
5832
+ var prevEntangledRenderLanesCursor = createCursor(NoLanes);
5817
5833
function pushHiddenContext(fiber, context) {
5818
- var prevRenderLanes = getRenderLanes ();
5819
- push(prevRenderLanesStackCursor, prevRenderLanes , fiber);
5834
+ var prevEntangledRenderLanes = getEntangledRenderLanes ();
5835
+ push(prevEntangledRenderLanesCursor, prevEntangledRenderLanes , fiber);
5820
5836
push(currentTreeHiddenStackCursor, context, fiber); // When rendering a subtree that's currently hidden, we must include all
5821
5837
// lanes that would have rendered if the hidden subtree hadn't been deferred.
5822
5838
// That is, in order to reveal content from hidden -> visible, we must commit
5823
5839
// all the updates that we skipped when we originally hid the tree.
5824
5840
5825
- setRenderLanes(mergeLanes(prevRenderLanes, context.baseLanes));
5841
+ setEntangledRenderLanes(
5842
+ mergeLanes(prevEntangledRenderLanes, context.baseLanes)
5843
+ );
5826
5844
}
5827
5845
function reuseHiddenContextOnStack(fiber) {
5828
5846
// This subtree is not currently hidden, so we don't need to add any lanes
5829
5847
// to the render lanes. But we still need to push something to avoid a
5830
5848
// context mismatch. Reuse the existing context on the stack.
5831
- push(prevRenderLanesStackCursor, getRenderLanes (), fiber);
5849
+ push(prevEntangledRenderLanesCursor, getEntangledRenderLanes (), fiber);
5832
5850
push(
5833
5851
currentTreeHiddenStackCursor,
5834
5852
currentTreeHiddenStackCursor.current,
@@ -5837,9 +5855,9 @@ function reuseHiddenContextOnStack(fiber) {
5837
5855
}
5838
5856
function popHiddenContext(fiber) {
5839
5857
// Restore the previous render lanes from the stack
5840
- setRenderLanes(prevRenderLanesStackCursor .current);
5858
+ setEntangledRenderLanes(prevEntangledRenderLanesCursor .current);
5841
5859
pop(currentTreeHiddenStackCursor, fiber);
5842
- pop(prevRenderLanesStackCursor , fiber);
5860
+ pop(prevEntangledRenderLanesCursor , fiber);
5843
5861
}
5844
5862
function isCurrentTreeHidden() {
5845
5863
return currentTreeHiddenStackCursor.current !== null;
@@ -6215,7 +6233,10 @@ function processRootScheduleInMicrotask() {
6215
6233
currentEventTransitionLane !== NoLane &&
6216
6234
shouldAttemptEagerTransition()
6217
6235
) {
6218
- markRootEntangled(root, mergeLanes(currentEventTransitionLane, SyncLane));
6236
+ // A transition was scheduled during an event, but we're going to try to
6237
+ // render it synchronously anyway. We do this during a popstate event to
6238
+ // preserve the scroll position of the previous page.
6239
+ upgradePendingLaneToSync(root, currentEventTransitionLane);
6219
6240
}
6220
6241
6221
6242
var nextLanes = scheduleTaskForRootDuringMicrotask(root, currentTime);
@@ -6624,7 +6645,7 @@ var didWarnAboutAsyncClientComponent;
6624
6645
// optimizations later.
6625
6646
// These are set right before calling the component.
6626
6647
6627
- var renderLanes$1 = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
6648
+ var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
6628
6649
// the work-in-progress hook.
6629
6650
6630
6651
var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
@@ -6867,7 +6888,7 @@ function renderWithHooks(
6867
6888
secondArg,
6868
6889
nextRenderLanes
6869
6890
) {
6870
- renderLanes$1 = nextRenderLanes;
6891
+ renderLanes = nextRenderLanes;
6871
6892
currentlyRenderingFiber$1 = workInProgress;
6872
6893
6873
6894
{
@@ -6968,7 +6989,7 @@ function finishRenderingHooks(current, workInProgress, Component) {
6968
6989
// hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
6969
6990
6970
6991
var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
6971
- renderLanes$1 = NoLanes;
6992
+ renderLanes = NoLanes;
6972
6993
currentlyRenderingFiber$1 = null;
6973
6994
currentHook = null;
6974
6995
workInProgressHook = null;
@@ -7202,7 +7223,7 @@ function resetHooksOnUnwind(workInProgress) {
7202
7223
didScheduleRenderPhaseUpdate = false;
7203
7224
}
7204
7225
7205
- renderLanes$1 = NoLanes;
7226
+ renderLanes = NoLanes;
7206
7227
currentlyRenderingFiber$1 = null;
7207
7228
currentHook = null;
7208
7229
workInProgressHook = null;
@@ -7468,7 +7489,7 @@ function updateReducerImpl(hook, current, reducer) {
7468
7489
7469
7490
var shouldSkipUpdate = isHiddenUpdate
7470
7491
? !isSubsetOfLanes(getWorkInProgressRootRenderLanes(), updateLane)
7471
- : !isSubsetOfLanes(renderLanes$1 , updateLane);
7492
+ : !isSubsetOfLanes(renderLanes, updateLane);
7472
7493
7473
7494
if (shouldSkipUpdate) {
7474
7495
// Priority is insufficient. Skip this update. If this is the first
@@ -7525,7 +7546,7 @@ function updateReducerImpl(hook, current, reducer) {
7525
7546
// sufficient, don't apply the update. Otherwise, apply the update,
7526
7547
// but leave it in the queue so it can be either reverted or
7527
7548
// rebased in a subsequent render.
7528
- if (isSubsetOfLanes(renderLanes$1 , revertLane)) {
7549
+ if (isSubsetOfLanes(renderLanes, revertLane)) {
7529
7550
// The transition that this optimistic update is associated with
7530
7551
// has finished. Pretend the update doesn't exist by skipping
7531
7552
// over it.
@@ -7698,7 +7719,9 @@ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
7698
7719
);
7699
7720
}
7700
7721
7701
- if (!includesBlockingLane(root, renderLanes$1)) {
7722
+ var rootRenderLanes = getWorkInProgressRootRenderLanes();
7723
+
7724
+ if (!includesBlockingLane(root, rootRenderLanes)) {
7702
7725
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
7703
7726
}
7704
7727
} // Read the current snapshot from the store on every render. This breaks the
@@ -7795,7 +7818,7 @@ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
7795
7818
);
7796
7819
}
7797
7820
7798
- if (!includesBlockingLane(root, renderLanes$1 )) {
7821
+ if (!includesBlockingLane(root, renderLanes)) {
7799
7822
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
7800
7823
}
7801
7824
}
@@ -8527,7 +8550,7 @@ function mountDeferredValueImpl(hook, value, initialValue) {
8527
8550
function updateDeferredValueImpl(hook, prevValue, value, initialValue) {
8528
8551
// TODO: We should also check if this component is going from
8529
8552
// hidden -> visible. If so, it should use the initialValue arg.
8530
- var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes$1 );
8553
+ var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes);
8531
8554
8532
8555
if (shouldDeferValue) {
8533
8556
// This is an urgent update. If the value has changed, keep using the
@@ -20811,9 +20834,9 @@ var workInProgressRootDidAttachPingListener = false; // A contextual version of
20811
20834
// HiddenContext module.
20812
20835
//
20813
20836
// Most things in the work loop should deal with workInProgressRootRenderLanes.
20814
- // Most things in begin/complete phases should deal with renderLanes .
20837
+ // Most things in begin/complete phases should deal with entangledRenderLanes .
20815
20838
20816
- var renderLanes = NoLanes; // Whether to root completed, errored, suspended, etc.
20839
+ var entangledRenderLanes = NoLanes; // Whether to root completed, errored, suspended, etc.
20817
20840
20818
20841
var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown
20819
20842
@@ -21596,11 +21619,11 @@ function flushSync(fn) {
21596
21619
// place that ever modifies it. Which module it lives in doesn't matter for
21597
21620
// performance because this function will get inlined regardless
21598
21621
21599
- function setRenderLanes(subtreeRenderLanes ) {
21600
- renderLanes = subtreeRenderLanes ;
21622
+ function setEntangledRenderLanes(newEntangledRenderLanes ) {
21623
+ entangledRenderLanes = newEntangledRenderLanes ;
21601
21624
}
21602
- function getRenderLanes () {
21603
- return renderLanes ;
21625
+ function getEntangledRenderLanes () {
21626
+ return entangledRenderLanes ;
21604
21627
}
21605
21628
21606
21629
function resetWorkInProgressStack() {
@@ -21651,7 +21674,7 @@ function prepareFreshStack(root, lanes) {
21651
21674
workInProgressRoot = root;
21652
21675
var rootWorkInProgress = createWorkInProgress(root.current, null);
21653
21676
workInProgress = rootWorkInProgress;
21654
- workInProgressRootRenderLanes = renderLanes = lanes;
21677
+ workInProgressRootRenderLanes = lanes;
21655
21678
workInProgressSuspendedReason = NotSuspended;
21656
21679
workInProgressThrownValue = null;
21657
21680
workInProgressRootDidAttachPingListener = false;
@@ -21661,7 +21684,15 @@ function prepareFreshStack(root, lanes) {
21661
21684
workInProgressRootInterleavedUpdatedLanes = NoLanes;
21662
21685
workInProgressRootPingedLanes = NoLanes;
21663
21686
workInProgressRootConcurrentErrors = null;
21664
- workInProgressRootRecoverableErrors = null;
21687
+ workInProgressRootRecoverableErrors = null; // Get the lanes that are entangled with whatever we're about to render. We
21688
+ // track these separately so we can distinguish the priority of the render
21689
+ // task from the priority of the lanes it is entangled with. For example, a
21690
+ // transition may not be allowed to finish unless it includes the Sync lane,
21691
+ // which is currently suspended. We should be able to render the Transition
21692
+ // and Sync lane in the same batch, but at Transition priority, because the
21693
+ // Sync lane already suspended.
21694
+
21695
+ entangledRenderLanes = getEntangledLanes(root, lanes);
21665
21696
finishQueueingConcurrentUpdates();
21666
21697
21667
21698
{
@@ -22251,10 +22282,10 @@ function performUnitOfWork(unitOfWork) {
22251
22282
22252
22283
if ((unitOfWork.mode & ProfileMode) !== NoMode) {
22253
22284
startProfilerTimer(unitOfWork);
22254
- next = beginWork(current, unitOfWork, renderLanes );
22285
+ next = beginWork(current, unitOfWork, entangledRenderLanes );
22255
22286
stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
22256
22287
} else {
22257
- next = beginWork(current, unitOfWork, renderLanes );
22288
+ next = beginWork(current, unitOfWork, entangledRenderLanes );
22258
22289
}
22259
22290
22260
22291
resetCurrentFiber();
@@ -22367,9 +22398,9 @@ function replaySuspendedUnitOfWork(unitOfWork) {
22367
22398
unwindInterruptedWork(current, unitOfWork);
22368
22399
unitOfWork = workInProgress = resetWorkInProgress(
22369
22400
unitOfWork,
22370
- renderLanes
22401
+ entangledRenderLanes
22371
22402
);
22372
- next = beginWork(current, unitOfWork, renderLanes );
22403
+ next = beginWork(current, unitOfWork, entangledRenderLanes );
22373
22404
break;
22374
22405
}
22375
22406
}
@@ -22479,10 +22510,10 @@ function completeUnitOfWork(unitOfWork) {
22479
22510
var next = void 0;
22480
22511
22481
22512
if ((completedWork.mode & ProfileMode) === NoMode) {
22482
- next = completeWork(current, completedWork, renderLanes );
22513
+ next = completeWork(current, completedWork, entangledRenderLanes );
22483
22514
} else {
22484
22515
startProfilerTimer(completedWork);
22485
- next = completeWork(current, completedWork, renderLanes ); // Update render duration assuming we didn't error.
22516
+ next = completeWork(current, completedWork, entangledRenderLanes ); // Update render duration assuming we didn't error.
22486
22517
22487
22518
stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
22488
22519
}
@@ -24770,7 +24801,7 @@ function createFiberRoot(
24770
24801
return root;
24771
24802
}
24772
24803
24773
- var ReactVersion = "18.3.0-canary-09fbee89d-20231013 ";
24804
+ var ReactVersion = "18.3.0-canary-309c8ad96-20231015 ";
24774
24805
24775
24806
// Might add PROFILE later.
24776
24807
0 commit comments