|
7 | 7 | * @noflow
|
8 | 8 | * @nolint
|
9 | 9 | * @preventMunge
|
10 |
| - * @generated SignedSource<<cfbc1c43d4da5c44f22471790ecd61bf>> |
| 10 | + * @generated SignedSource<<a30628fd998018c262d2437b0c9edc0e>> |
11 | 11 | */
|
12 | 12 |
|
13 | 13 | "use strict";
|
@@ -3238,7 +3238,9 @@ to return true:wantsResponderID| |
|
3238 | 3238 | dynamicFlags.passChildrenWhenCloningPersistedNodes,
|
3239 | 3239 | useMicrotasksForSchedulingInFabric =
|
3240 | 3240 | dynamicFlags.useMicrotasksForSchedulingInFabric,
|
3241 |
| - enableUnifiedSyncLane = dynamicFlags.enableUnifiedSyncLane; // The rest of the flags are static for better dead code elimination. |
| 3241 | + enableUnifiedSyncLane = dynamicFlags.enableUnifiedSyncLane, |
| 3242 | + enableInfiniteRenderLoopDetection = |
| 3243 | + dynamicFlags.enableInfiniteRenderLoopDetection; // The rest of the flags are static for better dead code elimination. |
3242 | 3244 | var enableSchedulingProfiler = true;
|
3243 | 3245 | var enableProfilerTimer = true;
|
3244 | 3246 | var enableProfilerCommitHooks = true;
|
@@ -23748,6 +23750,10 @@ to return true:wantsResponderID| |
|
23748 | 23750 | var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase.
|
23749 | 23751 |
|
23750 | 23752 | var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate
|
| 23753 | + // variable from the one for renders because the commit phase may run |
| 23754 | + // concurrently to a render phase. |
| 23755 | + |
| 23756 | + var didIncludeCommitPhaseUpdate = false; // The most recent time we either committed a fallback, or when a fallback was |
23751 | 23757 | // filled in with the resolved UI. This lets us throttle the appearance of new
|
23752 | 23758 | // content as it streams in, to minimize jank.
|
23753 | 23759 | // TODO: Think of a better name for this variable?
|
@@ -24439,10 +24445,36 @@ to return true:wantsResponderID| |
|
24439 | 24445 |
|
24440 | 24446 | function markRootUpdated(root, updatedLanes) {
|
24441 | 24447 | markRootUpdated$1(root, updatedLanes);
|
| 24448 | + |
| 24449 | + if (enableInfiniteRenderLoopDetection) { |
| 24450 | + // Check for recursive updates |
| 24451 | + if (executionContext & RenderContext) { |
| 24452 | + workInProgressRootDidIncludeRecursiveRenderUpdate = true; |
| 24453 | + } else if (executionContext & CommitContext) { |
| 24454 | + didIncludeCommitPhaseUpdate = true; |
| 24455 | + } |
| 24456 | + |
| 24457 | + throwIfInfiniteUpdateLoopDetected(); |
| 24458 | + } |
24442 | 24459 | }
|
24443 | 24460 |
|
24444 | 24461 | function markRootPinged(root, pingedLanes) {
|
24445 | 24462 | markRootPinged$1(root, pingedLanes);
|
| 24463 | + |
| 24464 | + if (enableInfiniteRenderLoopDetection) { |
| 24465 | + // Check for recursive pings. Pings are conceptually different from updates in |
| 24466 | + // other contexts but we call it an "update" in this context because |
| 24467 | + // repeatedly pinging a suspended render can cause a recursive render loop. |
| 24468 | + // The relevant property is that it can result in a new render attempt |
| 24469 | + // being scheduled. |
| 24470 | + if (executionContext & RenderContext) { |
| 24471 | + workInProgressRootDidIncludeRecursiveRenderUpdate = true; |
| 24472 | + } else if (executionContext & CommitContext) { |
| 24473 | + didIncludeCommitPhaseUpdate = true; |
| 24474 | + } |
| 24475 | + |
| 24476 | + throwIfInfiniteUpdateLoopDetected(); |
| 24477 | + } |
24446 | 24478 | }
|
24447 | 24479 |
|
24448 | 24480 | function markRootSuspended(root, suspendedLanes, spawnedLane) {
|
@@ -25796,6 +25828,8 @@ to return true:wantsResponderID| |
|
25796 | 25828 | remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes);
|
25797 | 25829 | markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates.
|
25798 | 25830 |
|
| 25831 | + didIncludeCommitPhaseUpdate = false; |
| 25832 | + |
25799 | 25833 | if (root === workInProgressRoot) {
|
25800 | 25834 | // We can reset these now that they are finished.
|
25801 | 25835 | workInProgressRoot = null;
|
@@ -25987,9 +26021,10 @@ to return true:wantsResponderID| |
|
25987 | 26021 | // Check if there was a recursive update spawned by this render, in either
|
25988 | 26022 | // the render phase or the commit phase. We track these explicitly because
|
25989 | 26023 | // we can't infer from the remaining lanes alone.
|
25990 |
| - // Was the finished render the result of an update (not hydration)? |
25991 |
| - includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? |
25992 |
| - includesSomeLane(remainingLanes, SyncUpdateLanes) |
| 26024 | + (enableInfiniteRenderLoopDetection && |
| 26025 | + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || // Was the finished render the result of an update (not hydration)? |
| 26026 | + (includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? |
| 26027 | + includesSomeLane(remainingLanes, SyncUpdateLanes)) |
25993 | 26028 | ) {
|
25994 | 26029 | {
|
25995 | 26030 | markNestedUpdateScheduled();
|
@@ -26422,6 +26457,19 @@ to return true:wantsResponderID| |
|
26422 | 26457 | rootWithNestedUpdates = null;
|
26423 | 26458 | rootWithPassiveNestedUpdates = null;
|
26424 | 26459 |
|
| 26460 | + if (enableInfiniteRenderLoopDetection) { |
| 26461 | + if (executionContext & RenderContext && workInProgressRoot !== null) { |
| 26462 | + // We're in the render phase. Disable the concurrent error recovery |
| 26463 | + // mechanism to ensure that the error we're about to throw gets handled. |
| 26464 | + // We need it to trigger the nearest error boundary so that the infinite |
| 26465 | + // update loop is broken. |
| 26466 | + workInProgressRoot.errorRecoveryDisabledLanes = mergeLanes( |
| 26467 | + workInProgressRoot.errorRecoveryDisabledLanes, |
| 26468 | + workInProgressRootRenderLanes |
| 26469 | + ); |
| 26470 | + } |
| 26471 | + } |
| 26472 | + |
26425 | 26473 | throw new Error(
|
26426 | 26474 | "Maximum update depth exceeded. This can happen when a component " +
|
26427 | 26475 | "repeatedly calls setState inside componentWillUpdate or " +
|
@@ -28042,7 +28090,7 @@ to return true:wantsResponderID| |
|
28042 | 28090 | return root;
|
28043 | 28091 | }
|
28044 | 28092 |
|
28045 |
| - var ReactVersion = "18.3.0-canary-26c89f2f"; |
| 28093 | + var ReactVersion = "18.3.0-canary-b1191c0d"; |
28046 | 28094 |
|
28047 | 28095 | function createPortal$1(
|
28048 | 28096 | children,
|
|
0 commit comments