From e0e832eabba035fac242b70f671520df520493ca Mon Sep 17 00:00:00 2001 From: kassens Date: Fri, 9 Feb 2024 16:19:24 +0000 Subject: [PATCH] Add infinite update loop detection (#28279) This is a partial redo of https://github.com/facebook/react/pull/26625. Since that was unlanded due to some detected breakages. This now includes a feature flag to be careful in rolling this out. DiffTrain build for [d8c1fa6b0b8da0512cb5acab9cd4f242451392f3](https://github.com/facebook/react/commit/d8c1fa6b0b8da0512cb5acab9cd4f242451392f3) --- compiled/facebook-www/REVISION | 2 +- compiled/facebook-www/React-prod.classic.js | 2 +- .../facebook-www/React-profiling.classic.js | 2 +- compiled/facebook-www/ReactART-dev.classic.js | 121 ++++++++++++-- compiled/facebook-www/ReactART-dev.modern.js | 121 ++++++++++++-- .../facebook-www/ReactART-prod.classic.js | 102 ++++++++---- compiled/facebook-www/ReactART-prod.modern.js | 102 ++++++++---- compiled/facebook-www/ReactDOM-dev.classic.js | 121 ++++++++++++-- compiled/facebook-www/ReactDOM-dev.modern.js | 121 ++++++++++++-- .../facebook-www/ReactDOM-prod.classic.js | 150 ++++++++++++------ compiled/facebook-www/ReactDOM-prod.modern.js | 150 ++++++++++++------ .../ReactDOM-profiling.classic.js | 136 +++++++++++----- .../facebook-www/ReactDOM-profiling.modern.js | 136 +++++++++++----- .../ReactDOMTesting-dev.classic.js | 121 ++++++++++++-- .../ReactDOMTesting-dev.modern.js | 121 ++++++++++++-- .../ReactDOMTesting-prod.classic.js | 150 ++++++++++++------ .../ReactDOMTesting-prod.modern.js | 150 ++++++++++++------ .../ReactTestRenderer-dev.classic.js | 65 ++++++-- .../ReactTestRenderer-dev.modern.js | 65 ++++++-- 19 files changed, 1479 insertions(+), 459 deletions(-) diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index c5df1125ed7c8..d9ff110cc83e7 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -ba5e6a8329c7194a2c573c037a37f24ce45ee58f +d8c1fa6b0b8da0512cb5acab9cd4f242451392f3 diff --git a/compiled/facebook-www/React-prod.classic.js b/compiled/facebook-www/React-prod.classic.js index cf8726f8adb19..bd5726ebf27c3 100644 --- a/compiled/facebook-www/React-prod.classic.js +++ b/compiled/facebook-www/React-prod.classic.js @@ -578,4 +578,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactCurrentDispatcher.current.useTransition(); }; -exports.version = "18.3.0-www-classic-ab0edb2e"; +exports.version = "18.3.0-www-classic-d27287f8"; diff --git a/compiled/facebook-www/React-profiling.classic.js b/compiled/facebook-www/React-profiling.classic.js index a9d505bc7b10d..f7b96769264e2 100644 --- a/compiled/facebook-www/React-profiling.classic.js +++ b/compiled/facebook-www/React-profiling.classic.js @@ -582,7 +582,7 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactCurrentDispatcher.current.useTransition(); }; -exports.version = "18.3.0-www-classic-5d6c9add"; +exports.version = "18.3.0-www-classic-08828b5d"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/compiled/facebook-www/ReactART-dev.classic.js b/compiled/facebook-www/ReactART-dev.classic.js index 80126b3b873a8..dc9b1927d5735 100644 --- a/compiled/facebook-www/ReactART-dev.classic.js +++ b/compiled/facebook-www/ReactART-dev.classic.js @@ -66,7 +66,7 @@ if (__DEV__) { return self; } - var ReactVersion = "18.3.0-www-classic-e77af7a1"; + var ReactVersion = "18.3.0-www-classic-bb651f27"; var LegacyRoot = 0; var ConcurrentRoot = 1; @@ -186,7 +186,9 @@ if (__DEV__) { retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = - dynamicFeatureFlags.transitionLaneExpirationMs; // On WWW, false is used for a new modern build. + dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection; // On WWW, false is used for a new modern build. var enableProfilerTimer = true; var enableProfilerCommitHooks = true; var enableProfilerNestedUpdatePhase = true; @@ -2214,7 +2216,7 @@ if (__DEV__) { return laneMap; } - function markRootUpdated(root, updateLane) { + function markRootUpdated$1(root, updateLane) { root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update // could unblock them. Clear the suspended lanes so that we can try rendering // them again. @@ -2251,7 +2253,7 @@ if (__DEV__) { markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } } - function markRootPinged(root, pingedLanes) { + function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes, spawnedLane) { @@ -25103,7 +25105,13 @@ if (__DEV__) { var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. // We will log them once the tree commits. - var workInProgressRootRecoverableErrors = null; // The most recent time we either committed a fallback, or when a fallback was + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate + // variable from the one for renders because the commit phase may run + // concurrently to a render phase. + + var didIncludeCommitPhaseUpdate = false; // The most recent time we either committed a fallback, or when a fallback was // filled in with the resolved UI. This lets us throttle the appearance of new // content as it streams in, to minimize jank. // TODO: Think of a better name for this variable? @@ -25813,6 +25821,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); } else { @@ -25846,6 +25855,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -25860,6 +25870,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -25871,6 +25882,7 @@ if (__DEV__) { finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -25895,14 +25907,26 @@ if (__DEV__) { // us that it's ready. This will be canceled if we start work on the // root again. root.cancelPendingCommit = schedulePendingCommit( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -25965,13 +25989,49 @@ if (__DEV__) { // eslint-disable-next-line no-unreachable return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + + function markRootUpdated(root, updatedLanes) { + markRootUpdated$1(root, updatedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive updates + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } + } + + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive pings. Pings are conceptually different from updates in + // other contexts but we call it an "update" in this context because + // repeatedly pinging a suspended render can cause a recursive render loop. + // The relevant property is that it can result in a new render attempt + // being scheduled. + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } } function markRootSuspended(root, suspendedLanes, spawnedLane) { // When suspending, we should always exclude lanes that were pinged or (more // rarely, since we try to avoid it) updated during the render phase. - // TODO: Lol maybe there's a better way to factor this besides this - // obnoxiously named function :) suspendedLanes = removeLanes( suspendedLanes, workInProgressRootPingedLanes @@ -25980,6 +26040,7 @@ if (__DEV__) { suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes, spawnedLane); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -26054,6 +26115,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -26183,7 +26245,8 @@ if (__DEV__) { workInProgressRootPingedLanes = NoLanes; workInProgressDeferredLane = NoLane; workInProgressRootConcurrentErrors = null; - workInProgressRootRecoverableErrors = null; // Get the lanes that are entangled with whatever we're about to render. We + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We // track these separately so we can distinguish the priority of the render // task from the priority of the lanes it is entangled with. For example, a // transition may not be allowed to finish unless it includes the Sync lane, @@ -27239,7 +27302,13 @@ if (__DEV__) { workInProgress = null; } - function commitRoot(root, recoverableErrors, transitions, spawnedLane) { + function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -27252,6 +27321,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -27267,6 +27337,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -27346,7 +27417,9 @@ if (__DEV__) { var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes, spawnedLane); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. + + didIncludeCommitPhaseUpdate = false; if (root === workInProgressRoot) { // We can reset these now that they are finished. @@ -27572,9 +27645,13 @@ if (__DEV__) { // hydration is conceptually not an update. if ( - // Was the finished render the result of an update (not hydration)? - includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? - includesSomeLane(remainingLanes, SyncUpdateLanes) + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || // Was the finished render the result of an update (not hydration)? + (includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? + includesSomeLane(remainingLanes, SyncUpdateLanes)) ) { { markNestedUpdateScheduled(); @@ -28076,6 +28153,20 @@ if (__DEV__) { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + + if (enableInfiniteRenderLoopDetection) { + if (executionContext & RenderContext && workInProgressRoot !== null) { + // We're in the render phase. Disable the concurrent error recovery + // mechanism to ensure that the error we're about to throw gets handled. + // We need it to trigger the nearest error boundary so that the infinite + // update loop is broken. + workInProgressRoot.errorRecoveryDisabledLanes = mergeLanes( + workInProgressRoot.errorRecoveryDisabledLanes, + workInProgressRootRenderLanes + ); + } + } + throw new Error( "Maximum update depth exceeded. This can happen when a component " + "repeatedly calls setState inside componentWillUpdate or " + diff --git a/compiled/facebook-www/ReactART-dev.modern.js b/compiled/facebook-www/ReactART-dev.modern.js index d90168820a373..df832fdb44893 100644 --- a/compiled/facebook-www/ReactART-dev.modern.js +++ b/compiled/facebook-www/ReactART-dev.modern.js @@ -66,7 +66,7 @@ if (__DEV__) { return self; } - var ReactVersion = "18.3.0-www-modern-fd7d3f3d"; + var ReactVersion = "18.3.0-www-modern-9dc3e827"; var LegacyRoot = 0; var ConcurrentRoot = 1; @@ -186,7 +186,9 @@ if (__DEV__) { retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = - dynamicFeatureFlags.transitionLaneExpirationMs; // On WWW, true is used for a new modern build. + dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection; // On WWW, true is used for a new modern build. var enableProfilerTimer = true; var enableProfilerCommitHooks = true; var enableProfilerNestedUpdatePhase = true; @@ -2211,7 +2213,7 @@ if (__DEV__) { return laneMap; } - function markRootUpdated(root, updateLane) { + function markRootUpdated$1(root, updateLane) { root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update // could unblock them. Clear the suspended lanes so that we can try rendering // them again. @@ -2248,7 +2250,7 @@ if (__DEV__) { markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } } - function markRootPinged(root, pingedLanes) { + function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes, spawnedLane) { @@ -24747,7 +24749,13 @@ if (__DEV__) { var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. // We will log them once the tree commits. - var workInProgressRootRecoverableErrors = null; // The most recent time we either committed a fallback, or when a fallback was + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate + // variable from the one for renders because the commit phase may run + // concurrently to a render phase. + + var didIncludeCommitPhaseUpdate = false; // The most recent time we either committed a fallback, or when a fallback was // filled in with the resolved UI. This lets us throttle the appearance of new // content as it streams in, to minimize jank. // TODO: Think of a better name for this variable? @@ -25457,6 +25465,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); } else { @@ -25490,6 +25499,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -25504,6 +25514,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -25515,6 +25526,7 @@ if (__DEV__) { finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -25539,14 +25551,26 @@ if (__DEV__) { // us that it's ready. This will be canceled if we start work on the // root again. root.cancelPendingCommit = schedulePendingCommit( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -25609,13 +25633,49 @@ if (__DEV__) { // eslint-disable-next-line no-unreachable return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + + function markRootUpdated(root, updatedLanes) { + markRootUpdated$1(root, updatedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive updates + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } + } + + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive pings. Pings are conceptually different from updates in + // other contexts but we call it an "update" in this context because + // repeatedly pinging a suspended render can cause a recursive render loop. + // The relevant property is that it can result in a new render attempt + // being scheduled. + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } } function markRootSuspended(root, suspendedLanes, spawnedLane) { // When suspending, we should always exclude lanes that were pinged or (more // rarely, since we try to avoid it) updated during the render phase. - // TODO: Lol maybe there's a better way to factor this besides this - // obnoxiously named function :) suspendedLanes = removeLanes( suspendedLanes, workInProgressRootPingedLanes @@ -25624,6 +25684,7 @@ if (__DEV__) { suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes, spawnedLane); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -25698,6 +25759,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -25827,7 +25889,8 @@ if (__DEV__) { workInProgressRootPingedLanes = NoLanes; workInProgressDeferredLane = NoLane; workInProgressRootConcurrentErrors = null; - workInProgressRootRecoverableErrors = null; // Get the lanes that are entangled with whatever we're about to render. We + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We // track these separately so we can distinguish the priority of the render // task from the priority of the lanes it is entangled with. For example, a // transition may not be allowed to finish unless it includes the Sync lane, @@ -26874,7 +26937,13 @@ if (__DEV__) { workInProgress = null; } - function commitRoot(root, recoverableErrors, transitions, spawnedLane) { + function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -26887,6 +26956,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -26902,6 +26972,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -26981,7 +27052,9 @@ if (__DEV__) { var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes, spawnedLane); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. + + didIncludeCommitPhaseUpdate = false; if (root === workInProgressRoot) { // We can reset these now that they are finished. @@ -27207,9 +27280,13 @@ if (__DEV__) { // hydration is conceptually not an update. if ( - // Was the finished render the result of an update (not hydration)? - includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? - includesSomeLane(remainingLanes, SyncUpdateLanes) + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || // Was the finished render the result of an update (not hydration)? + (includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? + includesSomeLane(remainingLanes, SyncUpdateLanes)) ) { { markNestedUpdateScheduled(); @@ -27711,6 +27788,20 @@ if (__DEV__) { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + + if (enableInfiniteRenderLoopDetection) { + if (executionContext & RenderContext && workInProgressRoot !== null) { + // We're in the render phase. Disable the concurrent error recovery + // mechanism to ensure that the error we're about to throw gets handled. + // We need it to trigger the nearest error boundary so that the infinite + // update loop is broken. + workInProgressRoot.errorRecoveryDisabledLanes = mergeLanes( + workInProgressRoot.errorRecoveryDisabledLanes, + workInProgressRootRenderLanes + ); + } + } + throw new Error( "Maximum update depth exceeded. This can happen when a component " + "repeatedly calls setState inside componentWillUpdate or " + diff --git a/compiled/facebook-www/ReactART-prod.classic.js b/compiled/facebook-www/ReactART-prod.classic.js index ec9ebcdc2a242..1460eee366672 100644 --- a/compiled/facebook-www/ReactART-prod.classic.js +++ b/compiled/facebook-www/ReactART-prod.classic.js @@ -83,6 +83,8 @@ var ReactSharedInternals = retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection, REACT_ELEMENT_TYPE = Symbol.for("react.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), @@ -558,11 +560,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 268435456 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -1175,12 +1172,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error(formatProdErrorMessage(185))) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -1271,6 +1263,7 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { workInProgressRootRenderLanes$12, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane )); } @@ -8510,6 +8503,8 @@ var DefaultCacheDispatcher = { workInProgressDeferredLane = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -8750,6 +8745,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -8762,6 +8758,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -8814,11 +8811,18 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -8854,6 +8858,16 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 268435456 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); +} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -8914,6 +8928,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; 0 === (root.current.mode & 32) && 0 !== (lanes & 8) && (lanes |= lanes & 32); var allEntangledLanes = root.entangledLanes; if (0 !== allEntangledLanes) @@ -9278,7 +9293,13 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions, spawnedLane) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig.transition; try { @@ -9288,6 +9309,7 @@ function commitRoot(root, recoverableErrors, transitions, spawnedLane) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -9301,6 +9323,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -9319,6 +9342,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -9382,7 +9406,9 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - 0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes) + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || + (0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes)) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -9524,6 +9550,11 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -9569,6 +9600,19 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + enableInfiniteRenderLoopDetection && + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error(formatProdErrorMessage(185))) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -10545,19 +10589,19 @@ var slice = Array.prototype.slice, }; return Text; })(React.Component), - devToolsConfig$jscomp$inline_1149 = { + devToolsConfig$jscomp$inline_1151 = { findFiberByHostInstance: function () { return null; }, bundleType: 0, - version: "18.3.0-www-classic-3603d4c1", + version: "18.3.0-www-classic-dfd84b0a", rendererPackageName: "react-art" }; -var internals$jscomp$inline_1320 = { - bundleType: devToolsConfig$jscomp$inline_1149.bundleType, - version: devToolsConfig$jscomp$inline_1149.version, - rendererPackageName: devToolsConfig$jscomp$inline_1149.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1149.rendererConfig, +var internals$jscomp$inline_1325 = { + bundleType: devToolsConfig$jscomp$inline_1151.bundleType, + version: devToolsConfig$jscomp$inline_1151.version, + rendererPackageName: devToolsConfig$jscomp$inline_1151.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1151.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -10574,26 +10618,26 @@ var internals$jscomp$inline_1320 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1149.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1151.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-classic-3603d4c1" + reconcilerVersion: "18.3.0-www-classic-dfd84b0a" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1321 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1326 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1321.isDisabled && - hook$jscomp$inline_1321.supportsFiber + !hook$jscomp$inline_1326.isDisabled && + hook$jscomp$inline_1326.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1321.inject( - internals$jscomp$inline_1320 + (rendererID = hook$jscomp$inline_1326.inject( + internals$jscomp$inline_1325 )), - (injectedHook = hook$jscomp$inline_1321); + (injectedHook = hook$jscomp$inline_1326); } catch (err) {} } var Path = Mode$1.Path; diff --git a/compiled/facebook-www/ReactART-prod.modern.js b/compiled/facebook-www/ReactART-prod.modern.js index 537854a50ff01..ca30580a93f5b 100644 --- a/compiled/facebook-www/ReactART-prod.modern.js +++ b/compiled/facebook-www/ReactART-prod.modern.js @@ -83,6 +83,8 @@ var ReactSharedInternals = retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection, REACT_ELEMENT_TYPE = Symbol.for("react.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), @@ -443,11 +445,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 268435456 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -982,12 +979,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error(formatProdErrorMessage(185))) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -1078,6 +1070,7 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { workInProgressRootRenderLanes$12, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane )); } @@ -8247,6 +8240,8 @@ var DefaultCacheDispatcher = { workInProgressDeferredLane = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -8487,6 +8482,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -8499,6 +8495,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -8551,11 +8548,18 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -8591,6 +8595,16 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 268435456 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); +} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -8651,6 +8665,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; 0 === (root.current.mode & 32) && 0 !== (lanes & 8) && (lanes |= lanes & 32); var allEntangledLanes = root.entangledLanes; if (0 !== allEntangledLanes) @@ -9011,7 +9026,13 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions, spawnedLane) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig.transition; try { @@ -9021,6 +9042,7 @@ function commitRoot(root, recoverableErrors, transitions, spawnedLane) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -9034,6 +9056,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -9052,6 +9075,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -9115,7 +9139,9 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - 0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes) + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || + (0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes)) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -9257,6 +9283,11 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -9302,6 +9333,19 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + enableInfiniteRenderLoopDetection && + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error(formatProdErrorMessage(185))) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -10211,19 +10255,19 @@ var slice = Array.prototype.slice, }; return Text; })(React.Component), - devToolsConfig$jscomp$inline_1129 = { + devToolsConfig$jscomp$inline_1131 = { findFiberByHostInstance: function () { return null; }, bundleType: 0, - version: "18.3.0-www-modern-aaaa6d78", + version: "18.3.0-www-modern-95ce9fd3", rendererPackageName: "react-art" }; -var internals$jscomp$inline_1300 = { - bundleType: devToolsConfig$jscomp$inline_1129.bundleType, - version: devToolsConfig$jscomp$inline_1129.version, - rendererPackageName: devToolsConfig$jscomp$inline_1129.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1129.rendererConfig, +var internals$jscomp$inline_1305 = { + bundleType: devToolsConfig$jscomp$inline_1131.bundleType, + version: devToolsConfig$jscomp$inline_1131.version, + rendererPackageName: devToolsConfig$jscomp$inline_1131.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1131.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -10240,26 +10284,26 @@ var internals$jscomp$inline_1300 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1129.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1131.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-modern-aaaa6d78" + reconcilerVersion: "18.3.0-www-modern-95ce9fd3" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1301 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1306 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1301.isDisabled && - hook$jscomp$inline_1301.supportsFiber + !hook$jscomp$inline_1306.isDisabled && + hook$jscomp$inline_1306.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1301.inject( - internals$jscomp$inline_1300 + (rendererID = hook$jscomp$inline_1306.inject( + internals$jscomp$inline_1305 )), - (injectedHook = hook$jscomp$inline_1301); + (injectedHook = hook$jscomp$inline_1306); } catch (err) {} } var Path = Mode$1.Path; diff --git a/compiled/facebook-www/ReactDOM-dev.classic.js b/compiled/facebook-www/ReactDOM-dev.classic.js index f075b5ed9da34..b15fe642009a2 100644 --- a/compiled/facebook-www/ReactDOM-dev.classic.js +++ b/compiled/facebook-www/ReactDOM-dev.classic.js @@ -151,7 +151,9 @@ if (__DEV__) { retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = - dynamicFeatureFlags.transitionLaneExpirationMs; // On WWW, false is used for a new modern build. + dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection; // On WWW, false is used for a new modern build. var enableProfilerTimer = true; var enableProfilerCommitHooks = true; var enableProfilerNestedUpdatePhase = true; @@ -2483,7 +2485,7 @@ if (__DEV__) { return laneMap; } - function markRootUpdated(root, updateLane) { + function markRootUpdated$1(root, updateLane) { root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update // could unblock them. Clear the suspended lanes so that we can try rendering // them again. @@ -2520,7 +2522,7 @@ if (__DEV__) { markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } } - function markRootPinged(root, pingedLanes) { + function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes, spawnedLane) { @@ -30887,7 +30889,13 @@ if (__DEV__) { var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. // We will log them once the tree commits. - var workInProgressRootRecoverableErrors = null; // The most recent time we either committed a fallback, or when a fallback was + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate + // variable from the one for renders because the commit phase may run + // concurrently to a render phase. + + var didIncludeCommitPhaseUpdate = false; // The most recent time we either committed a fallback, or when a fallback was // filled in with the resolved UI. This lets us throttle the appearance of new // content as it streams in, to minimize jank. // TODO: Think of a better name for this variable? @@ -31612,6 +31620,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); } else { @@ -31645,6 +31654,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -31659,6 +31669,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -31670,6 +31681,7 @@ if (__DEV__) { finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -31697,14 +31709,26 @@ if (__DEV__) { // us that it's ready. This will be canceled if we start work on the // root again. root.cancelPendingCommit = schedulePendingCommit( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -31767,13 +31791,49 @@ if (__DEV__) { // eslint-disable-next-line no-unreachable return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + + function markRootUpdated(root, updatedLanes) { + markRootUpdated$1(root, updatedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive updates + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } + } + + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive pings. Pings are conceptually different from updates in + // other contexts but we call it an "update" in this context because + // repeatedly pinging a suspended render can cause a recursive render loop. + // The relevant property is that it can result in a new render attempt + // being scheduled. + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } } function markRootSuspended(root, suspendedLanes, spawnedLane) { // When suspending, we should always exclude lanes that were pinged or (more // rarely, since we try to avoid it) updated during the render phase. - // TODO: Lol maybe there's a better way to factor this besides this - // obnoxiously named function :) suspendedLanes = removeLanes( suspendedLanes, workInProgressRootPingedLanes @@ -31782,6 +31842,7 @@ if (__DEV__) { suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes, spawnedLane); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -31856,6 +31917,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -32026,7 +32088,8 @@ if (__DEV__) { workInProgressRootPingedLanes = NoLanes; workInProgressDeferredLane = NoLane; workInProgressRootConcurrentErrors = null; - workInProgressRootRecoverableErrors = null; // Get the lanes that are entangled with whatever we're about to render. We + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We // track these separately so we can distinguish the priority of the render // task from the priority of the lanes it is entangled with. For example, a // transition may not be allowed to finish unless it includes the Sync lane, @@ -33082,7 +33145,13 @@ if (__DEV__) { workInProgress = null; } - function commitRoot(root, recoverableErrors, transitions, spawnedLane) { + function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -33095,6 +33164,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -33110,6 +33180,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -33189,7 +33260,9 @@ if (__DEV__) { var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes, spawnedLane); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. + + didIncludeCommitPhaseUpdate = false; if (root === workInProgressRoot) { // We can reset these now that they are finished. @@ -33430,9 +33503,13 @@ if (__DEV__) { // hydration is conceptually not an update. if ( - // Was the finished render the result of an update (not hydration)? - includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? - includesSomeLane(remainingLanes, SyncUpdateLanes) + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || // Was the finished render the result of an update (not hydration)? + (includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? + includesSomeLane(remainingLanes, SyncUpdateLanes)) ) { { markNestedUpdateScheduled(); @@ -33967,6 +34044,20 @@ if (__DEV__) { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + + if (enableInfiniteRenderLoopDetection) { + if (executionContext & RenderContext && workInProgressRoot !== null) { + // We're in the render phase. Disable the concurrent error recovery + // mechanism to ensure that the error we're about to throw gets handled. + // We need it to trigger the nearest error boundary so that the infinite + // update loop is broken. + workInProgressRoot.errorRecoveryDisabledLanes = mergeLanes( + workInProgressRoot.errorRecoveryDisabledLanes, + workInProgressRootRenderLanes + ); + } + } + throw new Error( "Maximum update depth exceeded. This can happen when a component " + "repeatedly calls setState inside componentWillUpdate or " + @@ -35719,7 +35810,7 @@ if (__DEV__) { return root; } - var ReactVersion = "18.3.0-www-classic-7dd01fd9"; + var ReactVersion = "18.3.0-www-classic-3d464e49"; function createPortal$1( children, diff --git a/compiled/facebook-www/ReactDOM-dev.modern.js b/compiled/facebook-www/ReactDOM-dev.modern.js index 73894176afc68..65ff1d49d9110 100644 --- a/compiled/facebook-www/ReactDOM-dev.modern.js +++ b/compiled/facebook-www/ReactDOM-dev.modern.js @@ -137,7 +137,9 @@ if (__DEV__) { retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = - dynamicFeatureFlags.transitionLaneExpirationMs; // On WWW, true is used for a new modern build. + dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection; // On WWW, true is used for a new modern build. var enableProfilerTimer = true; var enableProfilerCommitHooks = true; var enableProfilerNestedUpdatePhase = true; @@ -1831,7 +1833,7 @@ if (__DEV__) { return laneMap; } - function markRootUpdated(root, updateLane) { + function markRootUpdated$1(root, updateLane) { root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update // could unblock them. Clear the suspended lanes so that we can try rendering // them again. @@ -1868,7 +1870,7 @@ if (__DEV__) { markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } } - function markRootPinged(root, pingedLanes) { + function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes, spawnedLane) { @@ -30717,7 +30719,13 @@ if (__DEV__) { var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. // We will log them once the tree commits. - var workInProgressRootRecoverableErrors = null; // The most recent time we either committed a fallback, or when a fallback was + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate + // variable from the one for renders because the commit phase may run + // concurrently to a render phase. + + var didIncludeCommitPhaseUpdate = false; // The most recent time we either committed a fallback, or when a fallback was // filled in with the resolved UI. This lets us throttle the appearance of new // content as it streams in, to minimize jank. // TODO: Think of a better name for this variable? @@ -31442,6 +31450,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); } else { @@ -31475,6 +31484,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -31489,6 +31499,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -31500,6 +31511,7 @@ if (__DEV__) { finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -31527,14 +31539,26 @@ if (__DEV__) { // us that it's ready. This will be canceled if we start work on the // root again. root.cancelPendingCommit = schedulePendingCommit( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -31597,13 +31621,49 @@ if (__DEV__) { // eslint-disable-next-line no-unreachable return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + + function markRootUpdated(root, updatedLanes) { + markRootUpdated$1(root, updatedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive updates + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } + } + + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive pings. Pings are conceptually different from updates in + // other contexts but we call it an "update" in this context because + // repeatedly pinging a suspended render can cause a recursive render loop. + // The relevant property is that it can result in a new render attempt + // being scheduled. + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } } function markRootSuspended(root, suspendedLanes, spawnedLane) { // When suspending, we should always exclude lanes that were pinged or (more // rarely, since we try to avoid it) updated during the render phase. - // TODO: Lol maybe there's a better way to factor this besides this - // obnoxiously named function :) suspendedLanes = removeLanes( suspendedLanes, workInProgressRootPingedLanes @@ -31612,6 +31672,7 @@ if (__DEV__) { suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes, spawnedLane); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -31686,6 +31747,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -31856,7 +31918,8 @@ if (__DEV__) { workInProgressRootPingedLanes = NoLanes; workInProgressDeferredLane = NoLane; workInProgressRootConcurrentErrors = null; - workInProgressRootRecoverableErrors = null; // Get the lanes that are entangled with whatever we're about to render. We + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We // track these separately so we can distinguish the priority of the render // task from the priority of the lanes it is entangled with. For example, a // transition may not be allowed to finish unless it includes the Sync lane, @@ -32903,7 +32966,13 @@ if (__DEV__) { workInProgress = null; } - function commitRoot(root, recoverableErrors, transitions, spawnedLane) { + function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -32916,6 +32985,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -32931,6 +33001,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -33010,7 +33081,9 @@ if (__DEV__) { var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes, spawnedLane); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. + + didIncludeCommitPhaseUpdate = false; if (root === workInProgressRoot) { // We can reset these now that they are finished. @@ -33251,9 +33324,13 @@ if (__DEV__) { // hydration is conceptually not an update. if ( - // Was the finished render the result of an update (not hydration)? - includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? - includesSomeLane(remainingLanes, SyncUpdateLanes) + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || // Was the finished render the result of an update (not hydration)? + (includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? + includesSomeLane(remainingLanes, SyncUpdateLanes)) ) { { markNestedUpdateScheduled(); @@ -33788,6 +33865,20 @@ if (__DEV__) { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + + if (enableInfiniteRenderLoopDetection) { + if (executionContext & RenderContext && workInProgressRoot !== null) { + // We're in the render phase. Disable the concurrent error recovery + // mechanism to ensure that the error we're about to throw gets handled. + // We need it to trigger the nearest error boundary so that the infinite + // update loop is broken. + workInProgressRoot.errorRecoveryDisabledLanes = mergeLanes( + workInProgressRoot.errorRecoveryDisabledLanes, + workInProgressRootRenderLanes + ); + } + } + throw new Error( "Maximum update depth exceeded. This can happen when a component " + "repeatedly calls setState inside componentWillUpdate or " + @@ -35540,7 +35631,7 @@ if (__DEV__) { return root; } - var ReactVersion = "18.3.0-www-modern-9a48283c"; + var ReactVersion = "18.3.0-www-modern-ae0ae965"; function createPortal$1( children, diff --git a/compiled/facebook-www/ReactDOM-prod.classic.js b/compiled/facebook-www/ReactDOM-prod.classic.js index 17b1d73940f76..4309a0b369654 100644 --- a/compiled/facebook-www/ReactDOM-prod.classic.js +++ b/compiled/facebook-www/ReactDOM-prod.classic.js @@ -62,6 +62,8 @@ var ReactSharedInternals = retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection, REACT_ELEMENT_TYPE = Symbol.for("react.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), @@ -625,11 +627,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 268435456 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -1919,12 +1916,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error(formatProdErrorMessage(185))) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -2017,6 +2009,7 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { workInProgressRootRenderLanes$27, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane )); } @@ -10209,6 +10202,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressDeferredLane = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -10452,6 +10447,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -10464,6 +10460,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -10515,6 +10512,7 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -10526,12 +10524,24 @@ function commitRootWhenReady( null !== finishedWork) ) { root.cancelPendingCommit = finishedWork( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -10567,6 +10577,16 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 268435456 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); +} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -10662,6 +10682,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; 0 === (root.current.mode & 32) && 0 !== (lanes & 8) && (lanes |= lanes & 32); var allEntangledLanes = root.entangledLanes; if (0 !== allEntangledLanes) @@ -11033,7 +11054,13 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions, spawnedLane) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$1.transition; try { @@ -11043,6 +11070,7 @@ function commitRoot(root, recoverableErrors, transitions, spawnedLane) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -11056,6 +11084,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -11074,6 +11103,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -11147,7 +11177,9 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - 0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes) + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || + (0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes)) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -11306,6 +11338,11 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -11351,6 +11388,19 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + enableInfiniteRenderLoopDetection && + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error(formatProdErrorMessage(185))) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -13066,14 +13116,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$352; if (canUseDOM) { - var isSupported$jscomp$inline_1552 = "oninput" in document; - if (!isSupported$jscomp$inline_1552) { - var element$jscomp$inline_1553 = document.createElement("div"); - element$jscomp$inline_1553.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1552 = - "function" === typeof element$jscomp$inline_1553.oninput; + var isSupported$jscomp$inline_1554 = "oninput" in document; + if (!isSupported$jscomp$inline_1554) { + var element$jscomp$inline_1555 = document.createElement("div"); + element$jscomp$inline_1555.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1554 = + "function" === typeof element$jscomp$inline_1555.oninput; } - JSCompiler_inline_result$jscomp$352 = isSupported$jscomp$inline_1552; + JSCompiler_inline_result$jscomp$352 = isSupported$jscomp$inline_1554; } else JSCompiler_inline_result$jscomp$352 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$352 && @@ -13448,20 +13498,20 @@ function extractEvents$1( } } for ( - var i$jscomp$inline_1593 = 0; - i$jscomp$inline_1593 < simpleEventPluginEvents.length; - i$jscomp$inline_1593++ + var i$jscomp$inline_1595 = 0; + i$jscomp$inline_1595 < simpleEventPluginEvents.length; + i$jscomp$inline_1595++ ) { - var eventName$jscomp$inline_1594 = - simpleEventPluginEvents[i$jscomp$inline_1593], - domEventName$jscomp$inline_1595 = - eventName$jscomp$inline_1594.toLowerCase(), - capitalizedEvent$jscomp$inline_1596 = - eventName$jscomp$inline_1594[0].toUpperCase() + - eventName$jscomp$inline_1594.slice(1); + var eventName$jscomp$inline_1596 = + simpleEventPluginEvents[i$jscomp$inline_1595], + domEventName$jscomp$inline_1597 = + eventName$jscomp$inline_1596.toLowerCase(), + capitalizedEvent$jscomp$inline_1598 = + eventName$jscomp$inline_1596[0].toUpperCase() + + eventName$jscomp$inline_1596.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1595, - "on" + capitalizedEvent$jscomp$inline_1596 + domEventName$jscomp$inline_1597, + "on" + capitalizedEvent$jscomp$inline_1598 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -17153,17 +17203,17 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1820 = { +var devToolsConfig$jscomp$inline_1822 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-classic-563b132c", + version: "18.3.0-www-classic-e558c4d3", rendererPackageName: "react-dom" }; -var internals$jscomp$inline_2182 = { - bundleType: devToolsConfig$jscomp$inline_1820.bundleType, - version: devToolsConfig$jscomp$inline_1820.version, - rendererPackageName: devToolsConfig$jscomp$inline_1820.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1820.rendererConfig, +var internals$jscomp$inline_2187 = { + bundleType: devToolsConfig$jscomp$inline_1822.bundleType, + version: devToolsConfig$jscomp$inline_1822.version, + rendererPackageName: devToolsConfig$jscomp$inline_1822.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1822.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17179,26 +17229,26 @@ var internals$jscomp$inline_2182 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1820.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1822.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-classic-563b132c" + reconcilerVersion: "18.3.0-www-classic-e558c4d3" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_2183 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_2188 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_2183.isDisabled && - hook$jscomp$inline_2183.supportsFiber + !hook$jscomp$inline_2188.isDisabled && + hook$jscomp$inline_2188.supportsFiber ) try { - (rendererID = hook$jscomp$inline_2183.inject( - internals$jscomp$inline_2182 + (rendererID = hook$jscomp$inline_2188.inject( + internals$jscomp$inline_2187 )), - (injectedHook = hook$jscomp$inline_2183); + (injectedHook = hook$jscomp$inline_2188); } catch (err) {} } assign(Internals, { @@ -17536,4 +17586,4 @@ exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); throw Error(formatProdErrorMessage(248)); }; -exports.version = "18.3.0-www-classic-563b132c"; +exports.version = "18.3.0-www-classic-e558c4d3"; diff --git a/compiled/facebook-www/ReactDOM-prod.modern.js b/compiled/facebook-www/ReactDOM-prod.modern.js index 9a8f1ae8e4d37..2af0121f232e8 100644 --- a/compiled/facebook-www/ReactDOM-prod.modern.js +++ b/compiled/facebook-www/ReactDOM-prod.modern.js @@ -65,6 +65,8 @@ var assign = Object.assign, retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection, ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, @@ -383,11 +385,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 268435456 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -1813,12 +1810,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error(formatProdErrorMessage(185))) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -1911,6 +1903,7 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { workInProgressRootRenderLanes$27, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane )); } @@ -10046,6 +10039,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressDeferredLane = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -10289,6 +10284,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -10301,6 +10297,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -10352,6 +10349,7 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -10363,12 +10361,24 @@ function commitRootWhenReady( null !== finishedWork) ) { root.cancelPendingCommit = finishedWork( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -10404,6 +10414,16 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 268435456 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); +} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -10499,6 +10519,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; 0 === (root.current.mode & 32) && 0 !== (lanes & 8) && (lanes |= lanes & 32); var allEntangledLanes = root.entangledLanes; if (0 !== allEntangledLanes) @@ -10866,7 +10887,13 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions, spawnedLane) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$1.transition; try { @@ -10876,6 +10903,7 @@ function commitRoot(root, recoverableErrors, transitions, spawnedLane) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -10889,6 +10917,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -10907,6 +10936,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -10980,7 +11010,9 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - 0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes) + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || + (0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes)) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -11139,6 +11171,11 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -11184,6 +11221,19 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + enableInfiniteRenderLoopDetection && + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error(formatProdErrorMessage(185))) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -13435,14 +13485,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$350; if (canUseDOM) { - var isSupported$jscomp$inline_1552 = "oninput" in document; - if (!isSupported$jscomp$inline_1552) { - var element$jscomp$inline_1553 = document.createElement("div"); - element$jscomp$inline_1553.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1552 = - "function" === typeof element$jscomp$inline_1553.oninput; + var isSupported$jscomp$inline_1554 = "oninput" in document; + if (!isSupported$jscomp$inline_1554) { + var element$jscomp$inline_1555 = document.createElement("div"); + element$jscomp$inline_1555.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1554 = + "function" === typeof element$jscomp$inline_1555.oninput; } - JSCompiler_inline_result$jscomp$350 = isSupported$jscomp$inline_1552; + JSCompiler_inline_result$jscomp$350 = isSupported$jscomp$inline_1554; } else JSCompiler_inline_result$jscomp$350 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$350 && @@ -13754,20 +13804,20 @@ function registerSimpleEvent(domEventName, reactName) { registerTwoPhaseEvent(reactName, [domEventName]); } for ( - var i$jscomp$inline_1593 = 0; - i$jscomp$inline_1593 < simpleEventPluginEvents.length; - i$jscomp$inline_1593++ + var i$jscomp$inline_1595 = 0; + i$jscomp$inline_1595 < simpleEventPluginEvents.length; + i$jscomp$inline_1595++ ) { - var eventName$jscomp$inline_1594 = - simpleEventPluginEvents[i$jscomp$inline_1593], - domEventName$jscomp$inline_1595 = - eventName$jscomp$inline_1594.toLowerCase(), - capitalizedEvent$jscomp$inline_1596 = - eventName$jscomp$inline_1594[0].toUpperCase() + - eventName$jscomp$inline_1594.slice(1); + var eventName$jscomp$inline_1596 = + simpleEventPluginEvents[i$jscomp$inline_1595], + domEventName$jscomp$inline_1597 = + eventName$jscomp$inline_1596.toLowerCase(), + capitalizedEvent$jscomp$inline_1598 = + eventName$jscomp$inline_1596[0].toUpperCase() + + eventName$jscomp$inline_1596.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1595, - "on" + capitalizedEvent$jscomp$inline_1596 + domEventName$jscomp$inline_1597, + "on" + capitalizedEvent$jscomp$inline_1598 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -16680,17 +16730,17 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1779 = { +var devToolsConfig$jscomp$inline_1781 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-modern-bd1d4140", + version: "18.3.0-www-modern-55c0626f", rendererPackageName: "react-dom" }; -var internals$jscomp$inline_2146 = { - bundleType: devToolsConfig$jscomp$inline_1779.bundleType, - version: devToolsConfig$jscomp$inline_1779.version, - rendererPackageName: devToolsConfig$jscomp$inline_1779.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1779.rendererConfig, +var internals$jscomp$inline_2151 = { + bundleType: devToolsConfig$jscomp$inline_1781.bundleType, + version: devToolsConfig$jscomp$inline_1781.version, + rendererPackageName: devToolsConfig$jscomp$inline_1781.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1781.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -16707,26 +16757,26 @@ var internals$jscomp$inline_2146 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1779.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1781.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-modern-bd1d4140" + reconcilerVersion: "18.3.0-www-modern-55c0626f" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_2147 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_2152 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_2147.isDisabled && - hook$jscomp$inline_2147.supportsFiber + !hook$jscomp$inline_2152.isDisabled && + hook$jscomp$inline_2152.supportsFiber ) try { - (rendererID = hook$jscomp$inline_2147.inject( - internals$jscomp$inline_2146 + (rendererID = hook$jscomp$inline_2152.inject( + internals$jscomp$inline_2151 )), - (injectedHook = hook$jscomp$inline_2147); + (injectedHook = hook$jscomp$inline_2152); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; @@ -16992,4 +17042,4 @@ exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); throw Error(formatProdErrorMessage(248)); }; -exports.version = "18.3.0-www-modern-bd1d4140"; +exports.version = "18.3.0-www-modern-55c0626f"; diff --git a/compiled/facebook-www/ReactDOM-profiling.classic.js b/compiled/facebook-www/ReactDOM-profiling.classic.js index 206de25319c29..c65e27d40c296 100644 --- a/compiled/facebook-www/ReactDOM-profiling.classic.js +++ b/compiled/facebook-www/ReactDOM-profiling.classic.js @@ -66,6 +66,8 @@ var ReactSharedInternals = retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection, enableProfilerNestedUpdateScheduledHook = dynamicFeatureFlags.enableProfilerNestedUpdateScheduledHook, enableSchedulingProfiler = dynamicFeatureFlags.enableSchedulingProfiler, @@ -733,11 +735,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 268435456 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -2057,12 +2054,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error(formatProdErrorMessage(185))) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -2157,6 +2149,7 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { workInProgressRootRenderLanes$30, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane )); } @@ -10795,6 +10788,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressDeferredLane = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -11057,6 +11052,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -11069,6 +11065,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -11120,6 +11117,7 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -11131,12 +11129,24 @@ function commitRootWhenReady( null !== finishedWork) ) { root.cancelPendingCommit = finishedWork( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -11172,6 +11182,16 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 268435456 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); +} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -11267,6 +11287,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; 0 === (root.current.mode & 32) && 0 !== (lanes & 8) && (lanes |= lanes & 32); var allEntangledLanes = root.entangledLanes; if (0 !== allEntangledLanes) @@ -11715,7 +11736,13 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions, spawnedLane) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$1.transition; try { @@ -11725,6 +11752,7 @@ function commitRoot(root, recoverableErrors, transitions, spawnedLane) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -11738,6 +11766,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -11762,6 +11791,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -11851,7 +11881,9 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - 0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes) + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || + (0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes)) ? ((nestedUpdateScheduled = !0), root === rootWithNestedUpdates ? nestedUpdateCount++ @@ -12039,6 +12071,11 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -12084,6 +12121,19 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + enableInfiniteRenderLoopDetection && + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error(formatProdErrorMessage(185))) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -13835,14 +13885,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$373; if (canUseDOM) { - var isSupported$jscomp$inline_1637 = "oninput" in document; - if (!isSupported$jscomp$inline_1637) { - var element$jscomp$inline_1638 = document.createElement("div"); - element$jscomp$inline_1638.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1637 = - "function" === typeof element$jscomp$inline_1638.oninput; + var isSupported$jscomp$inline_1639 = "oninput" in document; + if (!isSupported$jscomp$inline_1639) { + var element$jscomp$inline_1640 = document.createElement("div"); + element$jscomp$inline_1640.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1639 = + "function" === typeof element$jscomp$inline_1640.oninput; } - JSCompiler_inline_result$jscomp$373 = isSupported$jscomp$inline_1637; + JSCompiler_inline_result$jscomp$373 = isSupported$jscomp$inline_1639; } else JSCompiler_inline_result$jscomp$373 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$373 && @@ -14217,20 +14267,20 @@ function extractEvents$1( } } for ( - var i$jscomp$inline_1678 = 0; - i$jscomp$inline_1678 < simpleEventPluginEvents.length; - i$jscomp$inline_1678++ + var i$jscomp$inline_1680 = 0; + i$jscomp$inline_1680 < simpleEventPluginEvents.length; + i$jscomp$inline_1680++ ) { - var eventName$jscomp$inline_1679 = - simpleEventPluginEvents[i$jscomp$inline_1678], - domEventName$jscomp$inline_1680 = - eventName$jscomp$inline_1679.toLowerCase(), - capitalizedEvent$jscomp$inline_1681 = - eventName$jscomp$inline_1679[0].toUpperCase() + - eventName$jscomp$inline_1679.slice(1); + var eventName$jscomp$inline_1681 = + simpleEventPluginEvents[i$jscomp$inline_1680], + domEventName$jscomp$inline_1682 = + eventName$jscomp$inline_1681.toLowerCase(), + capitalizedEvent$jscomp$inline_1683 = + eventName$jscomp$inline_1681[0].toUpperCase() + + eventName$jscomp$inline_1681.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1680, - "on" + capitalizedEvent$jscomp$inline_1681 + domEventName$jscomp$inline_1682, + "on" + capitalizedEvent$jscomp$inline_1683 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -17922,10 +17972,10 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1905 = { +var devToolsConfig$jscomp$inline_1907 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-classic-8953f036", + version: "18.3.0-www-classic-984218e2", rendererPackageName: "react-dom" }; (function (internals) { @@ -17943,10 +17993,10 @@ var devToolsConfig$jscomp$inline_1905 = { } catch (err) {} return hook.checkDCE ? !0 : !1; })({ - bundleType: devToolsConfig$jscomp$inline_1905.bundleType, - version: devToolsConfig$jscomp$inline_1905.version, - rendererPackageName: devToolsConfig$jscomp$inline_1905.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1905.rendererConfig, + bundleType: devToolsConfig$jscomp$inline_1907.bundleType, + version: devToolsConfig$jscomp$inline_1907.version, + rendererPackageName: devToolsConfig$jscomp$inline_1907.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1907.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17962,14 +18012,14 @@ var devToolsConfig$jscomp$inline_1905 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1905.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1907.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-classic-8953f036" + reconcilerVersion: "18.3.0-www-classic-984218e2" }); assign(Internals, { ReactBrowserEventEmitter: { @@ -18306,7 +18356,7 @@ exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); throw Error(formatProdErrorMessage(248)); }; -exports.version = "18.3.0-www-classic-8953f036"; +exports.version = "18.3.0-www-classic-984218e2"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/compiled/facebook-www/ReactDOM-profiling.modern.js b/compiled/facebook-www/ReactDOM-profiling.modern.js index b7064f389a67e..805f48bcee44d 100644 --- a/compiled/facebook-www/ReactDOM-profiling.modern.js +++ b/compiled/facebook-www/ReactDOM-profiling.modern.js @@ -69,6 +69,8 @@ var assign = Object.assign, retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection, enableProfilerNestedUpdateScheduledHook = dynamicFeatureFlags.enableProfilerNestedUpdateScheduledHook, enableSchedulingProfiler = dynamicFeatureFlags.enableSchedulingProfiler, @@ -491,11 +493,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 268435456 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -1951,12 +1948,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error(formatProdErrorMessage(185))) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -2051,6 +2043,7 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { workInProgressRootRenderLanes$30, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane )); } @@ -10626,6 +10619,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressDeferredLane = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -10888,6 +10883,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -10900,6 +10896,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -10951,6 +10948,7 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -10962,12 +10960,24 @@ function commitRootWhenReady( null !== finishedWork) ) { root.cancelPendingCommit = finishedWork( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -11003,6 +11013,16 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 268435456 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); +} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -11098,6 +11118,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; 0 === (root.current.mode & 32) && 0 !== (lanes & 8) && (lanes |= lanes & 32); var allEntangledLanes = root.entangledLanes; if (0 !== allEntangledLanes) @@ -11542,7 +11563,13 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions, spawnedLane) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$1.transition; try { @@ -11552,6 +11579,7 @@ function commitRoot(root, recoverableErrors, transitions, spawnedLane) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -11565,6 +11593,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -11589,6 +11618,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -11678,7 +11708,9 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - 0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes) + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || + (0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes)) ? ((nestedUpdateScheduled = !0), root === rootWithNestedUpdates ? nestedUpdateCount++ @@ -11866,6 +11898,11 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -11911,6 +11948,19 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + enableInfiniteRenderLoopDetection && + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error(formatProdErrorMessage(185))) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -14198,14 +14248,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$371; if (canUseDOM) { - var isSupported$jscomp$inline_1637 = "oninput" in document; - if (!isSupported$jscomp$inline_1637) { - var element$jscomp$inline_1638 = document.createElement("div"); - element$jscomp$inline_1638.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1637 = - "function" === typeof element$jscomp$inline_1638.oninput; + var isSupported$jscomp$inline_1639 = "oninput" in document; + if (!isSupported$jscomp$inline_1639) { + var element$jscomp$inline_1640 = document.createElement("div"); + element$jscomp$inline_1640.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1639 = + "function" === typeof element$jscomp$inline_1640.oninput; } - JSCompiler_inline_result$jscomp$371 = isSupported$jscomp$inline_1637; + JSCompiler_inline_result$jscomp$371 = isSupported$jscomp$inline_1639; } else JSCompiler_inline_result$jscomp$371 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$371 && @@ -14517,20 +14567,20 @@ function registerSimpleEvent(domEventName, reactName) { registerTwoPhaseEvent(reactName, [domEventName]); } for ( - var i$jscomp$inline_1678 = 0; - i$jscomp$inline_1678 < simpleEventPluginEvents.length; - i$jscomp$inline_1678++ + var i$jscomp$inline_1680 = 0; + i$jscomp$inline_1680 < simpleEventPluginEvents.length; + i$jscomp$inline_1680++ ) { - var eventName$jscomp$inline_1679 = - simpleEventPluginEvents[i$jscomp$inline_1678], - domEventName$jscomp$inline_1680 = - eventName$jscomp$inline_1679.toLowerCase(), - capitalizedEvent$jscomp$inline_1681 = - eventName$jscomp$inline_1679[0].toUpperCase() + - eventName$jscomp$inline_1679.slice(1); + var eventName$jscomp$inline_1681 = + simpleEventPluginEvents[i$jscomp$inline_1680], + domEventName$jscomp$inline_1682 = + eventName$jscomp$inline_1681.toLowerCase(), + capitalizedEvent$jscomp$inline_1683 = + eventName$jscomp$inline_1681[0].toUpperCase() + + eventName$jscomp$inline_1681.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1680, - "on" + capitalizedEvent$jscomp$inline_1681 + domEventName$jscomp$inline_1682, + "on" + capitalizedEvent$jscomp$inline_1683 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -17443,10 +17493,10 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1864 = { +var devToolsConfig$jscomp$inline_1866 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-modern-fd7d3f3d", + version: "18.3.0-www-modern-9dc3e827", rendererPackageName: "react-dom" }; (function (internals) { @@ -17464,10 +17514,10 @@ var devToolsConfig$jscomp$inline_1864 = { } catch (err) {} return hook.checkDCE ? !0 : !1; })({ - bundleType: devToolsConfig$jscomp$inline_1864.bundleType, - version: devToolsConfig$jscomp$inline_1864.version, - rendererPackageName: devToolsConfig$jscomp$inline_1864.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1864.rendererConfig, + bundleType: devToolsConfig$jscomp$inline_1866.bundleType, + version: devToolsConfig$jscomp$inline_1866.version, + rendererPackageName: devToolsConfig$jscomp$inline_1866.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1866.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17484,14 +17534,14 @@ var devToolsConfig$jscomp$inline_1864 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1864.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1866.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-modern-fd7d3f3d" + reconcilerVersion: "18.3.0-www-modern-9dc3e827" }); exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; exports.createPortal = function (children, container) { @@ -17756,7 +17806,7 @@ exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); throw Error(formatProdErrorMessage(248)); }; -exports.version = "18.3.0-www-modern-fd7d3f3d"; +exports.version = "18.3.0-www-modern-9dc3e827"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/compiled/facebook-www/ReactDOMTesting-dev.classic.js b/compiled/facebook-www/ReactDOMTesting-dev.classic.js index 61ee45f7153a2..72f2c55d3b9d4 100644 --- a/compiled/facebook-www/ReactDOMTesting-dev.classic.js +++ b/compiled/facebook-www/ReactDOMTesting-dev.classic.js @@ -143,7 +143,9 @@ if (__DEV__) { retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = - dynamicFeatureFlags.transitionLaneExpirationMs; // On WWW, false is used for a new modern build. + dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection; // On WWW, false is used for a new modern build. var enableProfilerTimer = true; var enableProfilerCommitHooks = true; var enableProfilerNestedUpdatePhase = true; @@ -2475,7 +2477,7 @@ if (__DEV__) { return laneMap; } - function markRootUpdated(root, updateLane) { + function markRootUpdated$1(root, updateLane) { root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update // could unblock them. Clear the suspended lanes so that we can try rendering // them again. @@ -2512,7 +2514,7 @@ if (__DEV__) { markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } } - function markRootPinged(root, pingedLanes) { + function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes, spawnedLane) { @@ -31511,7 +31513,13 @@ if (__DEV__) { var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. // We will log them once the tree commits. - var workInProgressRootRecoverableErrors = null; // The most recent time we either committed a fallback, or when a fallback was + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate + // variable from the one for renders because the commit phase may run + // concurrently to a render phase. + + var didIncludeCommitPhaseUpdate = false; // The most recent time we either committed a fallback, or when a fallback was // filled in with the resolved UI. This lets us throttle the appearance of new // content as it streams in, to minimize jank. // TODO: Think of a better name for this variable? @@ -32236,6 +32244,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); } else { @@ -32269,6 +32278,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -32283,6 +32293,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -32294,6 +32305,7 @@ if (__DEV__) { finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -32321,14 +32333,26 @@ if (__DEV__) { // us that it's ready. This will be canceled if we start work on the // root again. root.cancelPendingCommit = schedulePendingCommit( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -32391,13 +32415,49 @@ if (__DEV__) { // eslint-disable-next-line no-unreachable return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + + function markRootUpdated(root, updatedLanes) { + markRootUpdated$1(root, updatedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive updates + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } + } + + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive pings. Pings are conceptually different from updates in + // other contexts but we call it an "update" in this context because + // repeatedly pinging a suspended render can cause a recursive render loop. + // The relevant property is that it can result in a new render attempt + // being scheduled. + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } } function markRootSuspended(root, suspendedLanes, spawnedLane) { // When suspending, we should always exclude lanes that were pinged or (more // rarely, since we try to avoid it) updated during the render phase. - // TODO: Lol maybe there's a better way to factor this besides this - // obnoxiously named function :) suspendedLanes = removeLanes( suspendedLanes, workInProgressRootPingedLanes @@ -32406,6 +32466,7 @@ if (__DEV__) { suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes, spawnedLane); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -32480,6 +32541,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -32650,7 +32712,8 @@ if (__DEV__) { workInProgressRootPingedLanes = NoLanes; workInProgressDeferredLane = NoLane; workInProgressRootConcurrentErrors = null; - workInProgressRootRecoverableErrors = null; // Get the lanes that are entangled with whatever we're about to render. We + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We // track these separately so we can distinguish the priority of the render // task from the priority of the lanes it is entangled with. For example, a // transition may not be allowed to finish unless it includes the Sync lane, @@ -33706,7 +33769,13 @@ if (__DEV__) { workInProgress = null; } - function commitRoot(root, recoverableErrors, transitions, spawnedLane) { + function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -33719,6 +33788,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -33734,6 +33804,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -33813,7 +33884,9 @@ if (__DEV__) { var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes, spawnedLane); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. + + didIncludeCommitPhaseUpdate = false; if (root === workInProgressRoot) { // We can reset these now that they are finished. @@ -34054,9 +34127,13 @@ if (__DEV__) { // hydration is conceptually not an update. if ( - // Was the finished render the result of an update (not hydration)? - includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? - includesSomeLane(remainingLanes, SyncUpdateLanes) + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || // Was the finished render the result of an update (not hydration)? + (includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? + includesSomeLane(remainingLanes, SyncUpdateLanes)) ) { { markNestedUpdateScheduled(); @@ -34591,6 +34668,20 @@ if (__DEV__) { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + + if (enableInfiniteRenderLoopDetection) { + if (executionContext & RenderContext && workInProgressRoot !== null) { + // We're in the render phase. Disable the concurrent error recovery + // mechanism to ensure that the error we're about to throw gets handled. + // We need it to trigger the nearest error boundary so that the infinite + // update loop is broken. + workInProgressRoot.errorRecoveryDisabledLanes = mergeLanes( + workInProgressRoot.errorRecoveryDisabledLanes, + workInProgressRootRenderLanes + ); + } + } + throw new Error( "Maximum update depth exceeded. This can happen when a component " + "repeatedly calls setState inside componentWillUpdate or " + @@ -36343,7 +36434,7 @@ if (__DEV__) { return root; } - var ReactVersion = "18.3.0-www-classic-ab0edb2e"; + var ReactVersion = "18.3.0-www-classic-d27287f8"; function createPortal$1( children, diff --git a/compiled/facebook-www/ReactDOMTesting-dev.modern.js b/compiled/facebook-www/ReactDOMTesting-dev.modern.js index c89dc89f5a23c..d2f3281d80dc9 100644 --- a/compiled/facebook-www/ReactDOMTesting-dev.modern.js +++ b/compiled/facebook-www/ReactDOMTesting-dev.modern.js @@ -129,7 +129,9 @@ if (__DEV__) { retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = - dynamicFeatureFlags.transitionLaneExpirationMs; // On WWW, true is used for a new modern build. + dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection; // On WWW, true is used for a new modern build. var enableProfilerTimer = true; var enableProfilerCommitHooks = true; var enableProfilerNestedUpdatePhase = true; @@ -1823,7 +1825,7 @@ if (__DEV__) { return laneMap; } - function markRootUpdated(root, updateLane) { + function markRootUpdated$1(root, updateLane) { root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update // could unblock them. Clear the suspended lanes so that we can try rendering // them again. @@ -1860,7 +1862,7 @@ if (__DEV__) { markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } } - function markRootPinged(root, pingedLanes) { + function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes, spawnedLane) { @@ -31341,7 +31343,13 @@ if (__DEV__) { var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. // We will log them once the tree commits. - var workInProgressRootRecoverableErrors = null; // The most recent time we either committed a fallback, or when a fallback was + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate + // variable from the one for renders because the commit phase may run + // concurrently to a render phase. + + var didIncludeCommitPhaseUpdate = false; // The most recent time we either committed a fallback, or when a fallback was // filled in with the resolved UI. This lets us throttle the appearance of new // content as it streams in, to minimize jank. // TODO: Think of a better name for this variable? @@ -32066,6 +32074,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); } else { @@ -32099,6 +32108,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -32113,6 +32123,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -32124,6 +32135,7 @@ if (__DEV__) { finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -32151,14 +32163,26 @@ if (__DEV__) { // us that it's ready. This will be canceled if we start work on the // root again. root.cancelPendingCommit = schedulePendingCommit( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -32221,13 +32245,49 @@ if (__DEV__) { // eslint-disable-next-line no-unreachable return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + + function markRootUpdated(root, updatedLanes) { + markRootUpdated$1(root, updatedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive updates + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } + } + + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); + + if (enableInfiniteRenderLoopDetection) { + // Check for recursive pings. Pings are conceptually different from updates in + // other contexts but we call it an "update" in this context because + // repeatedly pinging a suspended render can cause a recursive render loop. + // The relevant property is that it can result in a new render attempt + // being scheduled. + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); + } } function markRootSuspended(root, suspendedLanes, spawnedLane) { // When suspending, we should always exclude lanes that were pinged or (more // rarely, since we try to avoid it) updated during the render phase. - // TODO: Lol maybe there's a better way to factor this besides this - // obnoxiously named function :) suspendedLanes = removeLanes( suspendedLanes, workInProgressRootPingedLanes @@ -32236,6 +32296,7 @@ if (__DEV__) { suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes, spawnedLane); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -32310,6 +32371,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -32480,7 +32542,8 @@ if (__DEV__) { workInProgressRootPingedLanes = NoLanes; workInProgressDeferredLane = NoLane; workInProgressRootConcurrentErrors = null; - workInProgressRootRecoverableErrors = null; // Get the lanes that are entangled with whatever we're about to render. We + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We // track these separately so we can distinguish the priority of the render // task from the priority of the lanes it is entangled with. For example, a // transition may not be allowed to finish unless it includes the Sync lane, @@ -33527,7 +33590,13 @@ if (__DEV__) { workInProgress = null; } - function commitRoot(root, recoverableErrors, transitions, spawnedLane) { + function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -33540,6 +33609,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -33555,6 +33625,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -33634,7 +33705,9 @@ if (__DEV__) { var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes, spawnedLane); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. + + didIncludeCommitPhaseUpdate = false; if (root === workInProgressRoot) { // We can reset these now that they are finished. @@ -33875,9 +33948,13 @@ if (__DEV__) { // hydration is conceptually not an update. if ( - // Was the finished render the result of an update (not hydration)? - includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? - includesSomeLane(remainingLanes, SyncUpdateLanes) + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || // Was the finished render the result of an update (not hydration)? + (includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? + includesSomeLane(remainingLanes, SyncUpdateLanes)) ) { { markNestedUpdateScheduled(); @@ -34412,6 +34489,20 @@ if (__DEV__) { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + + if (enableInfiniteRenderLoopDetection) { + if (executionContext & RenderContext && workInProgressRoot !== null) { + // We're in the render phase. Disable the concurrent error recovery + // mechanism to ensure that the error we're about to throw gets handled. + // We need it to trigger the nearest error boundary so that the infinite + // update loop is broken. + workInProgressRoot.errorRecoveryDisabledLanes = mergeLanes( + workInProgressRoot.errorRecoveryDisabledLanes, + workInProgressRootRenderLanes + ); + } + } + throw new Error( "Maximum update depth exceeded. This can happen when a component " + "repeatedly calls setState inside componentWillUpdate or " + @@ -36164,7 +36255,7 @@ if (__DEV__) { return root; } - var ReactVersion = "18.3.0-www-modern-bcbd09cb"; + var ReactVersion = "18.3.0-www-modern-387ac30c"; function createPortal$1( children, diff --git a/compiled/facebook-www/ReactDOMTesting-prod.classic.js b/compiled/facebook-www/ReactDOMTesting-prod.classic.js index 0a4d4b0d03fcc..8fbd82a1d691f 100644 --- a/compiled/facebook-www/ReactDOMTesting-prod.classic.js +++ b/compiled/facebook-www/ReactDOMTesting-prod.classic.js @@ -62,6 +62,8 @@ var ReactSharedInternals = retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection, REACT_ELEMENT_TYPE = Symbol.for("react.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), @@ -625,11 +627,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 268435456 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -2005,12 +2002,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error(formatProdErrorMessage(185))) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -2103,6 +2095,7 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { workInProgressRootRenderLanes$27, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane )); } @@ -10481,6 +10474,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressDeferredLane = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -10724,6 +10719,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -10736,6 +10732,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -10787,6 +10784,7 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -10798,12 +10796,24 @@ function commitRootWhenReady( null !== finishedWork) ) { root.cancelPendingCommit = finishedWork( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -10839,6 +10849,16 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 268435456 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); +} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -10934,6 +10954,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; 0 === (root.current.mode & 32) && 0 !== (lanes & 8) && (lanes |= lanes & 32); var allEntangledLanes = root.entangledLanes; if (0 !== allEntangledLanes) @@ -11305,7 +11326,13 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions, spawnedLane) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$1.transition; try { @@ -11315,6 +11342,7 @@ function commitRoot(root, recoverableErrors, transitions, spawnedLane) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -11328,6 +11356,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -11346,6 +11375,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -11419,7 +11449,9 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - 0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes) + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || + (0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes)) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -11578,6 +11610,11 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -11623,6 +11660,19 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + enableInfiniteRenderLoopDetection && + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error(formatProdErrorMessage(185))) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -13338,14 +13388,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$354; if (canUseDOM) { - var isSupported$jscomp$inline_1579 = "oninput" in document; - if (!isSupported$jscomp$inline_1579) { - var element$jscomp$inline_1580 = document.createElement("div"); - element$jscomp$inline_1580.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1579 = - "function" === typeof element$jscomp$inline_1580.oninput; + var isSupported$jscomp$inline_1581 = "oninput" in document; + if (!isSupported$jscomp$inline_1581) { + var element$jscomp$inline_1582 = document.createElement("div"); + element$jscomp$inline_1582.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1581 = + "function" === typeof element$jscomp$inline_1582.oninput; } - JSCompiler_inline_result$jscomp$354 = isSupported$jscomp$inline_1579; + JSCompiler_inline_result$jscomp$354 = isSupported$jscomp$inline_1581; } else JSCompiler_inline_result$jscomp$354 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$354 && @@ -13720,20 +13770,20 @@ function extractEvents$1( } } for ( - var i$jscomp$inline_1620 = 0; - i$jscomp$inline_1620 < simpleEventPluginEvents.length; - i$jscomp$inline_1620++ + var i$jscomp$inline_1622 = 0; + i$jscomp$inline_1622 < simpleEventPluginEvents.length; + i$jscomp$inline_1622++ ) { - var eventName$jscomp$inline_1621 = - simpleEventPluginEvents[i$jscomp$inline_1620], - domEventName$jscomp$inline_1622 = - eventName$jscomp$inline_1621.toLowerCase(), - capitalizedEvent$jscomp$inline_1623 = - eventName$jscomp$inline_1621[0].toUpperCase() + - eventName$jscomp$inline_1621.slice(1); + var eventName$jscomp$inline_1623 = + simpleEventPluginEvents[i$jscomp$inline_1622], + domEventName$jscomp$inline_1624 = + eventName$jscomp$inline_1623.toLowerCase(), + capitalizedEvent$jscomp$inline_1625 = + eventName$jscomp$inline_1623[0].toUpperCase() + + eventName$jscomp$inline_1623.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1622, - "on" + capitalizedEvent$jscomp$inline_1623 + domEventName$jscomp$inline_1624, + "on" + capitalizedEvent$jscomp$inline_1625 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -17482,17 +17532,17 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1825 = { +var devToolsConfig$jscomp$inline_1827 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-classic-5d6c9add", + version: "18.3.0-www-classic-08828b5d", rendererPackageName: "react-dom" }; -var internals$jscomp$inline_2194 = { - bundleType: devToolsConfig$jscomp$inline_1825.bundleType, - version: devToolsConfig$jscomp$inline_1825.version, - rendererPackageName: devToolsConfig$jscomp$inline_1825.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1825.rendererConfig, +var internals$jscomp$inline_2199 = { + bundleType: devToolsConfig$jscomp$inline_1827.bundleType, + version: devToolsConfig$jscomp$inline_1827.version, + rendererPackageName: devToolsConfig$jscomp$inline_1827.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1827.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17508,26 +17558,26 @@ var internals$jscomp$inline_2194 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1825.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1827.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-classic-5d6c9add" + reconcilerVersion: "18.3.0-www-classic-08828b5d" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_2195 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_2200 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_2195.isDisabled && - hook$jscomp$inline_2195.supportsFiber + !hook$jscomp$inline_2200.isDisabled && + hook$jscomp$inline_2200.supportsFiber ) try { - (rendererID = hook$jscomp$inline_2195.inject( - internals$jscomp$inline_2194 + (rendererID = hook$jscomp$inline_2200.inject( + internals$jscomp$inline_2199 )), - (injectedHook = hook$jscomp$inline_2195); + (injectedHook = hook$jscomp$inline_2200); } catch (err) {} } assign(Internals, { @@ -18016,4 +18066,4 @@ exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); throw Error(formatProdErrorMessage(248)); }; -exports.version = "18.3.0-www-classic-5d6c9add"; +exports.version = "18.3.0-www-classic-08828b5d"; diff --git a/compiled/facebook-www/ReactDOMTesting-prod.modern.js b/compiled/facebook-www/ReactDOMTesting-prod.modern.js index 0bfd8f673a880..d41f183fe67ac 100644 --- a/compiled/facebook-www/ReactDOMTesting-prod.modern.js +++ b/compiled/facebook-www/ReactDOMTesting-prod.modern.js @@ -65,6 +65,8 @@ var assign = Object.assign, retryLaneExpirationMs = dynamicFeatureFlags.retryLaneExpirationMs, syncLaneExpirationMs = dynamicFeatureFlags.syncLaneExpirationMs, transitionLaneExpirationMs = dynamicFeatureFlags.transitionLaneExpirationMs, + enableInfiniteRenderLoopDetection = + dynamicFeatureFlags.enableInfiniteRenderLoopDetection, ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, @@ -383,11 +385,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 268435456 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes, spawnedLane) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -1953,12 +1950,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 536870912)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error(formatProdErrorMessage(185))) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -2051,6 +2043,7 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { workInProgressRootRenderLanes$27, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane )); } @@ -10372,6 +10365,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressDeferredLane = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -10615,6 +10610,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -10627,6 +10623,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -10678,6 +10675,7 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -10689,12 +10687,24 @@ function commitRootWhenReady( null !== finishedWork) ) { root.cancelPendingCommit = finishedWork( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -10730,6 +10740,16 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 268435456 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); +} function markRootSuspended(root, suspendedLanes, spawnedLane) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -10825,6 +10845,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; 0 === (root.current.mode & 32) && 0 !== (lanes & 8) && (lanes |= lanes & 32); var allEntangledLanes = root.entangledLanes; if (0 !== allEntangledLanes) @@ -11192,7 +11213,13 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions, spawnedLane) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$1.transition; try { @@ -11202,6 +11229,7 @@ function commitRoot(root, recoverableErrors, transitions, spawnedLane) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -11215,6 +11243,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -11233,6 +11262,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes, spawnedLane); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -11306,7 +11336,9 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; - 0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes) + (enableInfiniteRenderLoopDetection && + (didIncludeRenderPhaseUpdate || didIncludeCommitPhaseUpdate)) || + (0 !== (lanes & 4194218) && 0 !== (remainingLanes & SyncUpdateLanes)) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -11465,6 +11497,11 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + enableInfiniteRenderLoopDetection && + (executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0), + throwIfInfiniteUpdateLoopDetected()); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -11510,6 +11547,19 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + enableInfiniteRenderLoopDetection && + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error(formatProdErrorMessage(185))) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -13761,14 +13811,14 @@ var isInputEventSupported = !1; if (canUseDOM) { var JSCompiler_inline_result$jscomp$352; if (canUseDOM) { - var isSupported$jscomp$inline_1579 = "oninput" in document; - if (!isSupported$jscomp$inline_1579) { - var element$jscomp$inline_1580 = document.createElement("div"); - element$jscomp$inline_1580.setAttribute("oninput", "return;"); - isSupported$jscomp$inline_1579 = - "function" === typeof element$jscomp$inline_1580.oninput; + var isSupported$jscomp$inline_1581 = "oninput" in document; + if (!isSupported$jscomp$inline_1581) { + var element$jscomp$inline_1582 = document.createElement("div"); + element$jscomp$inline_1582.setAttribute("oninput", "return;"); + isSupported$jscomp$inline_1581 = + "function" === typeof element$jscomp$inline_1582.oninput; } - JSCompiler_inline_result$jscomp$352 = isSupported$jscomp$inline_1579; + JSCompiler_inline_result$jscomp$352 = isSupported$jscomp$inline_1581; } else JSCompiler_inline_result$jscomp$352 = !1; isInputEventSupported = JSCompiler_inline_result$jscomp$352 && @@ -14080,20 +14130,20 @@ function registerSimpleEvent(domEventName, reactName) { registerTwoPhaseEvent(reactName, [domEventName]); } for ( - var i$jscomp$inline_1620 = 0; - i$jscomp$inline_1620 < simpleEventPluginEvents.length; - i$jscomp$inline_1620++ + var i$jscomp$inline_1622 = 0; + i$jscomp$inline_1622 < simpleEventPluginEvents.length; + i$jscomp$inline_1622++ ) { - var eventName$jscomp$inline_1621 = - simpleEventPluginEvents[i$jscomp$inline_1620], - domEventName$jscomp$inline_1622 = - eventName$jscomp$inline_1621.toLowerCase(), - capitalizedEvent$jscomp$inline_1623 = - eventName$jscomp$inline_1621[0].toUpperCase() + - eventName$jscomp$inline_1621.slice(1); + var eventName$jscomp$inline_1623 = + simpleEventPluginEvents[i$jscomp$inline_1622], + domEventName$jscomp$inline_1624 = + eventName$jscomp$inline_1623.toLowerCase(), + capitalizedEvent$jscomp$inline_1625 = + eventName$jscomp$inline_1623[0].toUpperCase() + + eventName$jscomp$inline_1623.slice(1); registerSimpleEvent( - domEventName$jscomp$inline_1622, - "on" + capitalizedEvent$jscomp$inline_1623 + domEventName$jscomp$inline_1624, + "on" + capitalizedEvent$jscomp$inline_1625 ); } registerSimpleEvent(ANIMATION_END, "onAnimationEnd"); @@ -17063,17 +17113,17 @@ Internals.Events = [ restoreStateIfNeeded, batchedUpdates$1 ]; -var devToolsConfig$jscomp$inline_1784 = { +var devToolsConfig$jscomp$inline_1786 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-modern-be690e4d", + version: "18.3.0-www-modern-6880028a", rendererPackageName: "react-dom" }; -var internals$jscomp$inline_2157 = { - bundleType: devToolsConfig$jscomp$inline_1784.bundleType, - version: devToolsConfig$jscomp$inline_1784.version, - rendererPackageName: devToolsConfig$jscomp$inline_1784.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1784.rendererConfig, +var internals$jscomp$inline_2162 = { + bundleType: devToolsConfig$jscomp$inline_1786.bundleType, + version: devToolsConfig$jscomp$inline_1786.version, + rendererPackageName: devToolsConfig$jscomp$inline_1786.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1786.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -17090,26 +17140,26 @@ var internals$jscomp$inline_2157 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1784.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1786.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-modern-be690e4d" + reconcilerVersion: "18.3.0-www-modern-6880028a" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_2158 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_2163 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_2158.isDisabled && - hook$jscomp$inline_2158.supportsFiber + !hook$jscomp$inline_2163.isDisabled && + hook$jscomp$inline_2163.supportsFiber ) try { - (rendererID = hook$jscomp$inline_2158.inject( - internals$jscomp$inline_2157 + (rendererID = hook$jscomp$inline_2163.inject( + internals$jscomp$inline_2162 )), - (injectedHook = hook$jscomp$inline_2158); + (injectedHook = hook$jscomp$inline_2163); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; @@ -17525,4 +17575,4 @@ exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); throw Error(formatProdErrorMessage(248)); }; -exports.version = "18.3.0-www-modern-be690e4d"; +exports.version = "18.3.0-www-modern-6880028a"; diff --git a/compiled/facebook-www/ReactTestRenderer-dev.classic.js b/compiled/facebook-www/ReactTestRenderer-dev.classic.js index 73a1534015be5..01a2ce588f307 100644 --- a/compiled/facebook-www/ReactTestRenderer-dev.classic.js +++ b/compiled/facebook-www/ReactTestRenderer-dev.classic.js @@ -1733,7 +1733,7 @@ if (__DEV__) { return laneMap; } - function markRootUpdated(root, updateLane) { + function markRootUpdated$1(root, updateLane) { root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update // could unblock them. Clear the suspended lanes so that we can try rendering // them again. @@ -1770,7 +1770,7 @@ if (__DEV__) { markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } } - function markRootPinged(root, pingedLanes) { + function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes, spawnedLane) { @@ -21965,7 +21965,9 @@ if (__DEV__) { var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. // We will log them once the tree commits. - var workInProgressRootRecoverableErrors = null; // The most recent time we either committed a fallback, or when a fallback was + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate // filled in with the resolved UI. This lets us throttle the appearance of new // content as it streams in, to minimize jank. // TODO: Think of a better name for this variable? @@ -22475,6 +22477,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); } else { @@ -22505,6 +22508,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -22519,6 +22523,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -22530,6 +22535,7 @@ if (__DEV__) { finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -22554,14 +22560,26 @@ if (__DEV__) { // us that it's ready. This will be canceled if we start work on the // root again. root.cancelPendingCommit = schedulePendingCommit( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -22624,13 +22642,23 @@ if (__DEV__) { // eslint-disable-next-line no-unreachable return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + + function markRootUpdated(root, updatedLanes) { + markRootUpdated$1(root, updatedLanes); + } + + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); } function markRootSuspended(root, suspendedLanes, spawnedLane) { // When suspending, we should always exclude lanes that were pinged or (more // rarely, since we try to avoid it) updated during the render phase. - // TODO: Lol maybe there's a better way to factor this besides this - // obnoxiously named function :) suspendedLanes = removeLanes( suspendedLanes, workInProgressRootPingedLanes @@ -22639,6 +22667,7 @@ if (__DEV__) { suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes, spawnedLane); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -22713,6 +22742,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -22857,7 +22887,8 @@ if (__DEV__) { workInProgressRootPingedLanes = NoLanes; workInProgressDeferredLane = NoLane; workInProgressRootConcurrentErrors = null; - workInProgressRootRecoverableErrors = null; // Get the lanes that are entangled with whatever we're about to render. We + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We // track these separately so we can distinguish the priority of the render // task from the priority of the lanes it is entangled with. For example, a // transition may not be allowed to finish unless it includes the Sync lane, @@ -23807,7 +23838,13 @@ if (__DEV__) { workInProgress = null; } - function commitRoot(root, recoverableErrors, transitions, spawnedLane) { + function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -23820,6 +23857,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -23835,6 +23873,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -23894,7 +23933,7 @@ if (__DEV__) { var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes, spawnedLane); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. if (root === workInProgressRoot) { // We can reset these now that they are finished. @@ -24082,6 +24121,9 @@ if (__DEV__) { // hydration is conceptually not an update. if ( + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. // Was the finished render the result of an update (not hydration)? includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? includesSomeLane(remainingLanes, SyncUpdateLanes) @@ -24529,6 +24571,7 @@ if (__DEV__) { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + throw new Error( "Maximum update depth exceeded. This can happen when a component " + "repeatedly calls setState inside componentWillUpdate or " + @@ -26053,7 +26096,7 @@ if (__DEV__) { return root; } - var ReactVersion = "18.3.0-www-classic-7e8de056"; + var ReactVersion = "18.3.0-www-classic-588d24ba"; // Might add PROFILE later. diff --git a/compiled/facebook-www/ReactTestRenderer-dev.modern.js b/compiled/facebook-www/ReactTestRenderer-dev.modern.js index c7f74b86aa078..809fe4a3d0b46 100644 --- a/compiled/facebook-www/ReactTestRenderer-dev.modern.js +++ b/compiled/facebook-www/ReactTestRenderer-dev.modern.js @@ -1733,7 +1733,7 @@ if (__DEV__) { return laneMap; } - function markRootUpdated(root, updateLane) { + function markRootUpdated$1(root, updateLane) { root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update // could unblock them. Clear the suspended lanes so that we can try rendering // them again. @@ -1770,7 +1770,7 @@ if (__DEV__) { markSpawnedDeferredLane(root, spawnedLane, suspendedLanes); } } - function markRootPinged(root, pingedLanes) { + function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes, spawnedLane) { @@ -21965,7 +21965,9 @@ if (__DEV__) { var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. // We will log them once the tree commits. - var workInProgressRootRecoverableErrors = null; // The most recent time we either committed a fallback, or when a fallback was + var workInProgressRootRecoverableErrors = null; // Tracks when an update occurs during the render phase. + + var workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Thacks when an update occurs during the commit phase. It's a separate // filled in with the resolved UI. This lets us throttle the appearance of new // content as it streams in, to minimize jank. // TODO: Think of a better name for this variable? @@ -22475,6 +22477,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); } else { @@ -22505,6 +22508,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ), @@ -22519,6 +22523,7 @@ if (__DEV__) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes, workInProgressDeferredLane ); @@ -22530,6 +22535,7 @@ if (__DEV__) { finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes, spawnedLane ) { @@ -22554,14 +22560,26 @@ if (__DEV__) { // us that it's ready. This will be canceled if we start work on the // root again. root.cancelPendingCommit = schedulePendingCommit( - commitRoot.bind(null, root, recoverableErrors, transitions) + commitRoot.bind( + null, + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate + ) ); markRootSuspended(root, lanes, spawnedLane); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions, spawnedLane); + commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -22624,13 +22642,23 @@ if (__DEV__) { // eslint-disable-next-line no-unreachable return true; + } // The extra indirections around markRootUpdated and markRootSuspended is + // needed to avoid a circular dependency between this module and + // ReactFiberLane. There's probably a better way to split up these modules and + // avoid this problem. Perhaps all the root-marking functions should move into + // the work loop. + + function markRootUpdated(root, updatedLanes) { + markRootUpdated$1(root, updatedLanes); + } + + function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); } function markRootSuspended(root, suspendedLanes, spawnedLane) { // When suspending, we should always exclude lanes that were pinged or (more // rarely, since we try to avoid it) updated during the render phase. - // TODO: Lol maybe there's a better way to factor this besides this - // obnoxiously named function :) suspendedLanes = removeLanes( suspendedLanes, workInProgressRootPingedLanes @@ -22639,6 +22667,7 @@ if (__DEV__) { suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes, spawnedLane); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -22713,6 +22742,7 @@ if (__DEV__) { root, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, workInProgressDeferredLane ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -22857,7 +22887,8 @@ if (__DEV__) { workInProgressRootPingedLanes = NoLanes; workInProgressDeferredLane = NoLane; workInProgressRootConcurrentErrors = null; - workInProgressRootRecoverableErrors = null; // Get the lanes that are entangled with whatever we're about to render. We + workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; // Get the lanes that are entangled with whatever we're about to render. We // track these separately so we can distinguish the priority of the render // task from the priority of the lanes it is entangled with. For example, a // transition may not be allowed to finish unless it includes the Sync lane, @@ -23807,7 +23838,13 @@ if (__DEV__) { workInProgress = null; } - function commitRoot(root, recoverableErrors, transitions, spawnedLane) { + function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate, + spawnedLane + ) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -23820,6 +23857,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority, spawnedLane ); @@ -23835,6 +23873,7 @@ if (__DEV__) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel, spawnedLane ) { @@ -23894,7 +23933,7 @@ if (__DEV__) { var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes, spawnedLane); + markRootFinished(root, remainingLanes, spawnedLane); // Reset this before firing side effects so we can detect recursive updates. if (root === workInProgressRoot) { // We can reset these now that they are finished. @@ -24082,6 +24121,9 @@ if (__DEV__) { // hydration is conceptually not an update. if ( + // Check if there was a recursive update spawned by this render, in either + // the render phase or the commit phase. We track these explicitly because + // we can't infer from the remaining lanes alone. // Was the finished render the result of an update (not hydration)? includesSomeLane(lanes, UpdateLanes) && // Did it schedule a sync update? includesSomeLane(remainingLanes, SyncUpdateLanes) @@ -24529,6 +24571,7 @@ if (__DEV__) { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + throw new Error( "Maximum update depth exceeded. This can happen when a component " + "repeatedly calls setState inside componentWillUpdate or " + @@ -26053,7 +26096,7 @@ if (__DEV__) { return root; } - var ReactVersion = "18.3.0-www-modern-9c82ad3d"; + var ReactVersion = "18.3.0-www-modern-623a68d9"; // Might add PROFILE later.