diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js index a4a3a4e3e3cdb..ddea712d03092 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<658af937953acc877e6c9c23bdafbf60>> */ 'use strict'; @@ -1584,7 +1584,7 @@ function createLaneMap(initial) { 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. @@ -1617,7 +1617,7 @@ function markRootSuspended$1(root, suspendedLanes) { lanes &= ~lane; } } -function markRootPinged(root, pingedLanes) { +function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes) { @@ -6004,6 +6004,21 @@ function ensureRootIsScheduled(root) { ReactCurrentActQueue$2.didScheduleLegacyUpdate = true; } } + +function unscheduleAllRoots() { + // This is only done in a fatal error situation, as a last resort to prevent + // an infinite render loop. + var root = firstScheduledRoot; + + while (root !== null) { + var next = root.next; + root.next = null; + root = next; + } + + firstScheduledRoot = lastScheduledRoot = null; +} + function flushSyncWorkOnAllRoots() { // This is allowed to be called synchronously, but the caller should check // the execution context first. @@ -6032,11 +6047,49 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { var workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes(); // There may or may not be synchronous work scheduled. Let's check. var didPerformSomeWork; + var nestedUpdatePasses = 0; var errors = null; isFlushingWork = true; do { - didPerformSomeWork = false; + didPerformSomeWork = false; // This outer loop re-runs if performing sync work on a root spawns + // additional sync work. If it happens too many times, it's very likely + // caused by some sort of infinite update loop. We already have a loop guard + // in place that will trigger an error on the n+1th update, but it's + // possible for that error to get swallowed if the setState is called from + // an unexpected place, like during the render phase. So as an added + // precaution, we also use a guard here. + // + // Ideally, there should be no known way to trigger this synchronous loop. + // It's really just here as a safety net. + // + // This limit is slightly larger than the one that throws inside setState, + // because that one is preferable because it includes a componens stack. + + if (++nestedUpdatePasses > 60) { + // This is a fatal error, so we'll unschedule all the roots. + unscheduleAllRoots(); // TODO: Change this error message to something different to distinguish + // it from the one that is thrown from setState. Those are less fatal + // because they usually will result in the bad component being unmounted, + // and an error boundary being triggered, rather than us having to + // forcibly stop the entire scheduler. + + var infiniteUpdateError = new Error( + "Maximum update depth exceeded. This can happen when a component " + + "repeatedly calls setState inside componentWillUpdate or " + + "componentDidUpdate. React limits the number of nested updates to " + + "prevent infinite loops." + ); + + if (errors === null) { + errors = [infiniteUpdateError]; + } else { + errors.push(infiniteUpdateError); + } + + break; + } + var root = firstScheduledRoot; while (root !== null) { @@ -19938,7 +19991,13 @@ var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during th 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? @@ -20420,7 +20479,8 @@ function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { commitRoot( root, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate ); } else { if (includesOnlyRetries(lanes) && alwaysThrottleRetries) { @@ -20450,6 +20510,7 @@ function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ), msUntilTimeout @@ -20463,6 +20524,7 @@ function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ); } @@ -20473,6 +20535,7 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes ) { // TODO: Combine retry throttling with Suspensey commits. Right now they run @@ -20496,14 +20559,20 @@ function commitRootWhenReady( // 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); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions); + commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -20566,18 +20635,49 @@ function isRenderConsistentWithExternalStores(finishedWork) { // 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); // Check for recursive updates + + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); +} + +function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); // 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) { // 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); suspendedLanes = removeLanes( suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -20648,7 +20748,8 @@ function performSyncWorkOnRoot(root) { commitRoot( root, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -20789,6 +20890,7 @@ function prepareFreshStack(root, lanes) { workInProgressRootPingedLanes = NoLanes; workInProgressRootConcurrentErrors = null; workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; finishQueueingConcurrentUpdates(); { @@ -21685,7 +21787,12 @@ function unwindUnitOfWork(unitOfWork) { workInProgress = null; } -function commitRoot(root, recoverableErrors, transitions) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate +) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -21698,6 +21805,7 @@ function commitRoot(root, recoverableErrors, transitions) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority ); } finally { @@ -21712,6 +21820,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel ) { do { @@ -21767,7 +21876,9 @@ function commitRootImpl( var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes); + markRootFinished(root, remainingLanes); // 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. @@ -21948,7 +22059,18 @@ function commitRootImpl( remainingLanes = root.pendingLanes; - if (includesSyncLane(remainingLanes)) { + 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. + didIncludeCommitPhaseUpdate || + didIncludeRenderPhaseUpdate || // As an additional precaution, we also check if there's any remaining sync + // work. Theoretically this should be unreachable but if there's a mistake + // in React it helps to be overly defensive given how hard it is to debug + // those scenarios otherwise. This won't catch recursive async updates, + // though, which is why we check the flags above first. + includesSyncLane(remainingLanes) + ) { { markNestedUpdateScheduled(); } // Count the number of times the root synchronously re-renders without @@ -22386,6 +22508,18 @@ function throwIfInfiniteUpdateLoopDetected() { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + + 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 " + @@ -23857,7 +23991,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.3.0-canary-80d9a4011-20230627"; +var ReactVersion = "18.3.0-canary-822386f25-20230627"; // Might add PROFILE later. diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js index 01ab4e134f55d..1698efd647337 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<66065d19e6aa88d1eec3aaef75c93277>> + * @generated SignedSource<> */ "use strict"; @@ -466,11 +466,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -758,14 +753,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 1073741824)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -1975,10 +1963,23 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { var workInProgressRoot$jscomp$0 = workInProgressRoot, workInProgressRootRenderLanes$jscomp$0 = workInProgressRootRenderLanes, + nestedUpdatePasses = 0, errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; + if (60 < ++nestedUpdatePasses) { + for (onlyLegacy = firstScheduledRoot; null !== onlyLegacy; ) + (workInProgressRoot$jscomp$0 = onlyLegacy.next), + (onlyLegacy.next = null), + (onlyLegacy = workInProgressRoot$jscomp$0); + firstScheduledRoot = lastScheduledRoot = null; + onlyLegacy = Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ); + null === errors ? (errors = [onlyLegacy]) : errors.push(onlyLegacy); + break; + } for (var root = firstScheduledRoot; null !== root; ) { if ( (!onlyLegacy || 0 === root.tag) && @@ -2030,7 +2031,8 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { commitRoot( root$jscomp$0, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate )); } ensureRootIsScheduled(root$jscomp$0); @@ -6388,6 +6390,8 @@ var DefaultCacheDispatcher = { workInProgressRootPingedLanes = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -6541,6 +6545,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { originallyAttemptedLanes, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ), didTimeout @@ -6552,6 +6557,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { originallyAttemptedLanes, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ); } @@ -6601,10 +6607,11 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes ) { 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); - commitRoot(root, recoverableErrors, transitions); + commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -6640,6 +6647,15 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 536870912 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); +} function markRootSuspended(root, suspendedLanes) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -6716,6 +6732,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; finishQueueingConcurrentUpdates(); return root; } @@ -7196,7 +7213,12 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig.transition; try { @@ -7206,6 +7228,7 @@ function commitRoot(root, recoverableErrors, transitions) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority ); } finally { @@ -7218,6 +7241,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel ) { do flushPassiveEffects(); @@ -7239,6 +7263,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -7302,6 +7327,8 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; + didIncludeCommitPhaseUpdate || + didIncludeRenderPhaseUpdate || 0 !== (remainingLanes & 3) ? root === rootWithNestedUpdates ? nestedUpdateCount++ @@ -7436,6 +7463,10 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -7483,6 +7514,20 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -8596,19 +8641,19 @@ function wrapFiber(fiber) { fiberToWrapper.set(fiber, wrapper)); return wrapper; } -var devToolsConfig$jscomp$inline_1031 = { +var devToolsConfig$jscomp$inline_1036 = { findFiberByHostInstance: function () { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "18.3.0-canary-80d9a4011-20230627", + version: "18.3.0-canary-822386f25-20230627", rendererPackageName: "react-test-renderer" }; -var internals$jscomp$inline_1230 = { - bundleType: devToolsConfig$jscomp$inline_1031.bundleType, - version: devToolsConfig$jscomp$inline_1031.version, - rendererPackageName: devToolsConfig$jscomp$inline_1031.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1031.rendererConfig, +var internals$jscomp$inline_1238 = { + bundleType: devToolsConfig$jscomp$inline_1036.bundleType, + version: devToolsConfig$jscomp$inline_1036.version, + rendererPackageName: devToolsConfig$jscomp$inline_1036.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1036.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8625,26 +8670,26 @@ var internals$jscomp$inline_1230 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1031.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1036.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-80d9a4011-20230627" + reconcilerVersion: "18.3.0-canary-822386f25-20230627" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1231 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1239 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1231.isDisabled && - hook$jscomp$inline_1231.supportsFiber + !hook$jscomp$inline_1239.isDisabled && + hook$jscomp$inline_1239.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1231.inject( - internals$jscomp$inline_1230 + (rendererID = hook$jscomp$inline_1239.inject( + internals$jscomp$inline_1238 )), - (injectedHook = hook$jscomp$inline_1231); + (injectedHook = hook$jscomp$inline_1239); } catch (err) {} } exports._Scheduler = Scheduler; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js index 7b3c593327ce5..cebc85f8cc509 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<122479e7a309e602a4eea949c69aac02>> + * @generated SignedSource<> */ "use strict"; @@ -484,11 +484,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -776,14 +771,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 1073741824)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -1993,10 +1981,23 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { var workInProgressRoot$jscomp$0 = workInProgressRoot, workInProgressRootRenderLanes$jscomp$0 = workInProgressRootRenderLanes, + nestedUpdatePasses = 0, errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; + if (60 < ++nestedUpdatePasses) { + for (onlyLegacy = firstScheduledRoot; null !== onlyLegacy; ) + (workInProgressRoot$jscomp$0 = onlyLegacy.next), + (onlyLegacy.next = null), + (onlyLegacy = workInProgressRoot$jscomp$0); + firstScheduledRoot = lastScheduledRoot = null; + onlyLegacy = Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ); + null === errors ? (errors = [onlyLegacy]) : errors.push(onlyLegacy); + break; + } for (var root = firstScheduledRoot; null !== root; ) { if ( (!onlyLegacy || 0 === root.tag) && @@ -2050,7 +2051,8 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { commitRoot( root$jscomp$0, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate )); } ensureRootIsScheduled(root$jscomp$0); @@ -6726,6 +6728,8 @@ var DefaultCacheDispatcher = { workInProgressRootPingedLanes = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -6881,6 +6885,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { originallyAttemptedLanes, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ), didTimeout @@ -6892,6 +6897,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { originallyAttemptedLanes, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ); } @@ -6941,10 +6947,11 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes ) { 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); - commitRoot(root, recoverableErrors, transitions); + commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -6980,6 +6987,15 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 536870912 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); +} function markRootSuspended(root, suspendedLanes) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -7056,6 +7072,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; finishQueueingConcurrentUpdates(); return root; } @@ -7557,7 +7574,12 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig.transition; try { @@ -7567,6 +7589,7 @@ function commitRoot(root, recoverableErrors, transitions) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority ); } finally { @@ -7579,6 +7602,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel ) { do flushPassiveEffects(); @@ -7600,6 +7624,7 @@ function commitRootImpl( var remainingLanes = finishedWork.lanes | finishedWork.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -7664,6 +7689,8 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; + didIncludeCommitPhaseUpdate || + didIncludeRenderPhaseUpdate || 0 !== (remainingLanes & 3) ? ((nestedUpdateScheduled = !0), root === rootWithNestedUpdates @@ -7844,6 +7871,10 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -7891,6 +7922,20 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -9022,19 +9067,19 @@ function wrapFiber(fiber) { fiberToWrapper.set(fiber, wrapper)); return wrapper; } -var devToolsConfig$jscomp$inline_1073 = { +var devToolsConfig$jscomp$inline_1078 = { findFiberByHostInstance: function () { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "18.3.0-canary-80d9a4011-20230627", + version: "18.3.0-canary-822386f25-20230627", rendererPackageName: "react-test-renderer" }; -var internals$jscomp$inline_1271 = { - bundleType: devToolsConfig$jscomp$inline_1073.bundleType, - version: devToolsConfig$jscomp$inline_1073.version, - rendererPackageName: devToolsConfig$jscomp$inline_1073.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1073.rendererConfig, +var internals$jscomp$inline_1279 = { + bundleType: devToolsConfig$jscomp$inline_1078.bundleType, + version: devToolsConfig$jscomp$inline_1078.version, + rendererPackageName: devToolsConfig$jscomp$inline_1078.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1078.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -9051,26 +9096,26 @@ var internals$jscomp$inline_1271 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1073.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1078.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-80d9a4011-20230627" + reconcilerVersion: "18.3.0-canary-822386f25-20230627" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1272 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1280 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1272.isDisabled && - hook$jscomp$inline_1272.supportsFiber + !hook$jscomp$inline_1280.isDisabled && + hook$jscomp$inline_1280.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1272.inject( - internals$jscomp$inline_1271 + (rendererID = hook$jscomp$inline_1280.inject( + internals$jscomp$inline_1279 )), - (injectedHook = hook$jscomp$inline_1272); + (injectedHook = hook$jscomp$inline_1280); } catch (err) {} } exports._Scheduler = Scheduler; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js index 883ff93e24a5b..af812977a5e51 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js @@ -27,7 +27,7 @@ if ( } "use strict"; -var ReactVersion = "18.3.0-canary-80d9a4011-20230627"; +var ReactVersion = "18.3.0-canary-822386f25-20230627"; // ATTENTION // When adding new symbols to this file, diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js index 478796f15b393..aa391489941bb 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js @@ -623,4 +623,4 @@ exports.useSyncExternalStore = function ( ); }; exports.useTransition = useTransition; -exports.version = "18.3.0-canary-80d9a4011-20230627"; +exports.version = "18.3.0-canary-822386f25-20230627"; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js index 25f8a1eaa038f..8817e953e6cf0 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js @@ -626,7 +626,7 @@ exports.useSyncExternalStore = function ( ); }; exports.useTransition = useTransition; -exports.version = "18.3.0-canary-80d9a4011-20230627"; +exports.version = "18.3.0-canary-822386f25-20230627"; /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if ( diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION index c7051172ed13f..da2fe1e236860 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION @@ -1 +1 @@ -80d9a40114bb43c07d021e8254790852f450bd2b +822386f252fd1f0e949efa904a1ed790133329f7 diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index 334e2b67a6763..506a512ffafd7 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<282d999e7d51d0f42b6870e93255b637>> */ 'use strict'; @@ -4492,7 +4492,7 @@ function createLaneMap(initial) { 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. @@ -4525,7 +4525,7 @@ function markRootSuspended$1(root, suspendedLanes) { lanes &= ~lane; } } -function markRootPinged(root, pingedLanes) { +function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes) { @@ -9731,6 +9731,21 @@ function ensureRootIsScheduled(root) { ReactCurrentActQueue$2.didScheduleLegacyUpdate = true; } } + +function unscheduleAllRoots() { + // This is only done in a fatal error situation, as a last resort to prevent + // an infinite render loop. + var root = firstScheduledRoot; + + while (root !== null) { + var next = root.next; + root.next = null; + root = next; + } + + firstScheduledRoot = lastScheduledRoot = null; +} + function flushSyncWorkOnAllRoots() { // This is allowed to be called synchronously, but the caller should check // the execution context first. @@ -9759,11 +9774,49 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { var workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes(); // There may or may not be synchronous work scheduled. Let's check. var didPerformSomeWork; + var nestedUpdatePasses = 0; var errors = null; isFlushingWork = true; do { - didPerformSomeWork = false; + didPerformSomeWork = false; // This outer loop re-runs if performing sync work on a root spawns + // additional sync work. If it happens too many times, it's very likely + // caused by some sort of infinite update loop. We already have a loop guard + // in place that will trigger an error on the n+1th update, but it's + // possible for that error to get swallowed if the setState is called from + // an unexpected place, like during the render phase. So as an added + // precaution, we also use a guard here. + // + // Ideally, there should be no known way to trigger this synchronous loop. + // It's really just here as a safety net. + // + // This limit is slightly larger than the one that throws inside setState, + // because that one is preferable because it includes a componens stack. + + if (++nestedUpdatePasses > 60) { + // This is a fatal error, so we'll unschedule all the roots. + unscheduleAllRoots(); // TODO: Change this error message to something different to distinguish + // it from the one that is thrown from setState. Those are less fatal + // because they usually will result in the bad component being unmounted, + // and an error boundary being triggered, rather than us having to + // forcibly stop the entire scheduler. + + var infiniteUpdateError = new Error( + "Maximum update depth exceeded. This can happen when a component " + + "repeatedly calls setState inside componentWillUpdate or " + + "componentDidUpdate. React limits the number of nested updates to " + + "prevent infinite loops." + ); + + if (errors === null) { + errors = [infiniteUpdateError]; + } else { + errors.push(infiniteUpdateError); + } + + break; + } + var root = firstScheduledRoot; while (root !== null) { @@ -22766,7 +22819,13 @@ var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during th 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? @@ -23254,7 +23313,8 @@ function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { commitRoot( root, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate ); } else { if ( @@ -23287,6 +23347,7 @@ function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ), msUntilTimeout @@ -23300,6 +23361,7 @@ function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ); } @@ -23310,6 +23372,7 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes ) { // TODO: Combine retry throttling with Suspensey commits. Right now they run @@ -23333,14 +23396,20 @@ function commitRootWhenReady( // 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); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions); + commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -23403,18 +23472,49 @@ function isRenderConsistentWithExternalStores(finishedWork) { // 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); // Check for recursive updates + + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); +} + +function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); // 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) { // 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); suspendedLanes = removeLanes( suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -23485,7 +23585,8 @@ function performSyncWorkOnRoot(root) { commitRoot( root, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -23626,6 +23727,7 @@ function prepareFreshStack(root, lanes) { workInProgressRootPingedLanes = NoLanes; workInProgressRootConcurrentErrors = null; workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; finishQueueingConcurrentUpdates(); { @@ -24586,7 +24688,12 @@ function unwindUnitOfWork(unitOfWork) { workInProgress = null; } -function commitRoot(root, recoverableErrors, transitions) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate +) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -24599,6 +24706,7 @@ function commitRoot(root, recoverableErrors, transitions) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority ); } finally { @@ -24613,6 +24721,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel ) { do { @@ -24676,7 +24785,9 @@ function commitRootImpl( var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes); + markRootFinished(root, remainingLanes); // 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. @@ -24859,7 +24970,18 @@ function commitRootImpl( remainingLanes = root.pendingLanes; - if (includesSyncLane(remainingLanes)) { + 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. + didIncludeCommitPhaseUpdate || + didIncludeRenderPhaseUpdate || // As an additional precaution, we also check if there's any remaining sync + // work. Theoretically this should be unreachable but if there's a mistake + // in React it helps to be overly defensive given how hard it is to debug + // those scenarios otherwise. This won't catch recursive async updates, + // though, which is why we check the flags above first. + includesSyncLane(remainingLanes) + ) { { markNestedUpdateScheduled(); } // Count the number of times the root synchronously re-renders without @@ -25284,6 +25406,18 @@ function throwIfInfiniteUpdateLoopDetected() { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + + 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 " + @@ -26896,7 +27030,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.3.0-canary-24413a06"; +var ReactVersion = "18.3.0-canary-1fdda267"; function createPortal$1( children, diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index b208154436149..4b976c2484148 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<6c39bbaa5e58faafb8b0955ba16581df>> + * @generated SignedSource<<5252391e1925919eea8b5aff457183b3>> */ "use strict"; @@ -1509,11 +1509,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -2126,14 +2121,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 1073741824)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -3345,10 +3333,23 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { var workInProgressRoot$jscomp$0 = workInProgressRoot, workInProgressRootRenderLanes$jscomp$0 = workInProgressRootRenderLanes, + nestedUpdatePasses = 0, errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; + if (60 < ++nestedUpdatePasses) { + for (onlyLegacy = firstScheduledRoot; null !== onlyLegacy; ) + (workInProgressRoot$jscomp$0 = onlyLegacy.next), + (onlyLegacy.next = null), + (onlyLegacy = workInProgressRoot$jscomp$0); + firstScheduledRoot = lastScheduledRoot = null; + onlyLegacy = Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ); + null === errors ? (errors = [onlyLegacy]) : errors.push(onlyLegacy); + break; + } for (var root = firstScheduledRoot; null !== root; ) { if ( (!onlyLegacy || 0 === root.tag) && @@ -3400,7 +3401,8 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { commitRoot( root$jscomp$0, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate )); } ensureRootIsScheduled(root$jscomp$0); @@ -7401,6 +7403,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressRootPingedLanes = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -7566,6 +7570,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ), exitStatus @@ -7577,6 +7582,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ); } @@ -7626,10 +7632,11 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes ) { 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); - commitRoot(root, recoverableErrors, transitions); + commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -7665,6 +7672,15 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 536870912 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); +} function markRootSuspended(root, suspendedLanes) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -7718,6 +7734,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; finishQueueingConcurrentUpdates(); return root; } @@ -8189,7 +8206,12 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig.transition; try { @@ -8199,6 +8221,7 @@ function commitRoot(root, recoverableErrors, transitions) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority ); } finally { @@ -8211,6 +8234,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel ) { do flushPassiveEffects(); @@ -8232,6 +8256,7 @@ function commitRootImpl( var remainingLanes = transitions.lanes | transitions.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -8292,6 +8317,8 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; + didIncludeCommitPhaseUpdate || + didIncludeRenderPhaseUpdate || 0 !== (remainingLanes & 3) ? root === rootWithNestedUpdates ? nestedUpdateCount++ @@ -8407,6 +8434,10 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -8454,6 +8485,20 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -9405,10 +9450,10 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1042 = { + devToolsConfig$jscomp$inline_1047 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "18.3.0-canary-7b440937", + version: "18.3.0-canary-235fe204", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -9424,11 +9469,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1284 = { - bundleType: devToolsConfig$jscomp$inline_1042.bundleType, - version: devToolsConfig$jscomp$inline_1042.version, - rendererPackageName: devToolsConfig$jscomp$inline_1042.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1042.rendererConfig, +var internals$jscomp$inline_1292 = { + bundleType: devToolsConfig$jscomp$inline_1047.bundleType, + version: devToolsConfig$jscomp$inline_1047.version, + rendererPackageName: devToolsConfig$jscomp$inline_1047.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1047.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -9444,26 +9489,26 @@ var internals$jscomp$inline_1284 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1042.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1047.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-7b440937" + reconcilerVersion: "18.3.0-canary-235fe204" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1285 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1293 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1285.isDisabled && - hook$jscomp$inline_1285.supportsFiber + !hook$jscomp$inline_1293.isDisabled && + hook$jscomp$inline_1293.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1285.inject( - internals$jscomp$inline_1284 + (rendererID = hook$jscomp$inline_1293.inject( + internals$jscomp$inline_1292 )), - (injectedHook = hook$jscomp$inline_1285); + (injectedHook = hook$jscomp$inline_1293); } catch (err) {} } exports.createPortal = function (children, containerTag) { diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 97e5bd4541bac..a4fe892cb9850 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<506b43d751458f22815d7d9f5b4c0d6a>> + * @generated SignedSource<<1e7d01283543cc2574e9236933f570be>> */ @@ -1607,11 +1607,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -2254,14 +2249,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 1073741824)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -3473,10 +3461,23 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { var workInProgressRoot$jscomp$0 = workInProgressRoot, workInProgressRootRenderLanes$jscomp$0 = workInProgressRootRenderLanes, + nestedUpdatePasses = 0, errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; + if (60 < ++nestedUpdatePasses) { + for (onlyLegacy = firstScheduledRoot; null !== onlyLegacy; ) + (workInProgressRoot$jscomp$0 = onlyLegacy.next), + (onlyLegacy.next = null), + (onlyLegacy = workInProgressRoot$jscomp$0); + firstScheduledRoot = lastScheduledRoot = null; + onlyLegacy = Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ); + null === errors ? (errors = [onlyLegacy]) : errors.push(onlyLegacy); + break; + } for (var root = firstScheduledRoot; null !== root; ) { if ( (!onlyLegacy || 0 === root.tag) && @@ -3530,7 +3531,8 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { commitRoot( root$jscomp$0, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate )); } ensureRootIsScheduled(root$jscomp$0); @@ -7929,6 +7931,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressRootPingedLanes = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -8097,6 +8101,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ), exitStatus @@ -8108,6 +8113,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ); } @@ -8157,10 +8163,11 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes ) { 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); - commitRoot(root, recoverableErrors, transitions); + commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -8196,6 +8203,15 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 536870912 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); +} function markRootSuspended(root, suspendedLanes) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -8249,6 +8265,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; finishQueueingConcurrentUpdates(); return root; } @@ -8797,7 +8814,12 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig.transition; try { @@ -8807,6 +8829,7 @@ function commitRoot(root, recoverableErrors, transitions) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority ); } finally { @@ -8819,6 +8842,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel ) { do flushPassiveEffects(); @@ -8843,6 +8867,7 @@ function commitRootImpl( var remainingLanes = transitions.lanes | transitions.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -8911,6 +8936,8 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; + didIncludeCommitPhaseUpdate || + didIncludeRenderPhaseUpdate || 0 !== (remainingLanes & 3) ? ((nestedUpdateScheduled = !0), root === rootWithNestedUpdates @@ -9083,6 +9110,10 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -9130,6 +9161,20 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -10114,10 +10159,10 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1120 = { + devToolsConfig$jscomp$inline_1125 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "18.3.0-canary-0830b591", + version: "18.3.0-canary-0b3b38d1", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10147,10 +10192,10 @@ var roots = new Map(), } catch (err) {} return hook.checkDCE ? !0 : !1; })({ - bundleType: devToolsConfig$jscomp$inline_1120.bundleType, - version: devToolsConfig$jscomp$inline_1120.version, - rendererPackageName: devToolsConfig$jscomp$inline_1120.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1120.rendererConfig, + bundleType: devToolsConfig$jscomp$inline_1125.bundleType, + version: devToolsConfig$jscomp$inline_1125.version, + rendererPackageName: devToolsConfig$jscomp$inline_1125.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1125.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -10166,14 +10211,14 @@ var roots = new Map(), return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1120.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1125.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-0830b591" + reconcilerVersion: "18.3.0-canary-0b3b38d1" }); exports.createPortal = function (children, containerTag) { return createPortal$1( diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index 9b39307a2e482..e58b9acb4441a 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<6cb022a94ef524b9885df5654088f4d4>> */ 'use strict'; @@ -5353,7 +5353,7 @@ function createLaneMap(initial) { 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. @@ -5386,7 +5386,7 @@ function markRootSuspended$1(root, suspendedLanes) { lanes &= ~lane; } } -function markRootPinged(root, pingedLanes) { +function markRootPinged$1(root, pingedLanes) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } function markRootFinished(root, remainingLanes) { @@ -10048,6 +10048,21 @@ function ensureRootIsScheduled(root) { ReactCurrentActQueue$2.didScheduleLegacyUpdate = true; } } + +function unscheduleAllRoots() { + // This is only done in a fatal error situation, as a last resort to prevent + // an infinite render loop. + var root = firstScheduledRoot; + + while (root !== null) { + var next = root.next; + root.next = null; + root = next; + } + + firstScheduledRoot = lastScheduledRoot = null; +} + function flushSyncWorkOnAllRoots() { // This is allowed to be called synchronously, but the caller should check // the execution context first. @@ -10076,11 +10091,49 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { var workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes(); // There may or may not be synchronous work scheduled. Let's check. var didPerformSomeWork; + var nestedUpdatePasses = 0; var errors = null; isFlushingWork = true; do { - didPerformSomeWork = false; + didPerformSomeWork = false; // This outer loop re-runs if performing sync work on a root spawns + // additional sync work. If it happens too many times, it's very likely + // caused by some sort of infinite update loop. We already have a loop guard + // in place that will trigger an error on the n+1th update, but it's + // possible for that error to get swallowed if the setState is called from + // an unexpected place, like during the render phase. So as an added + // precaution, we also use a guard here. + // + // Ideally, there should be no known way to trigger this synchronous loop. + // It's really just here as a safety net. + // + // This limit is slightly larger than the one that throws inside setState, + // because that one is preferable because it includes a componens stack. + + if (++nestedUpdatePasses > 60) { + // This is a fatal error, so we'll unschedule all the roots. + unscheduleAllRoots(); // TODO: Change this error message to something different to distinguish + // it from the one that is thrown from setState. Those are less fatal + // because they usually will result in the bad component being unmounted, + // and an error boundary being triggered, rather than us having to + // forcibly stop the entire scheduler. + + var infiniteUpdateError = new Error( + "Maximum update depth exceeded. This can happen when a component " + + "repeatedly calls setState inside componentWillUpdate or " + + "componentDidUpdate. React limits the number of nested updates to " + + "prevent infinite loops." + ); + + if (errors === null) { + errors = [infiniteUpdateError]; + } else { + errors.push(infiniteUpdateError); + } + + break; + } + var root = firstScheduledRoot; while (root !== null) { @@ -23280,7 +23333,13 @@ var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during th 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? @@ -23768,7 +23827,8 @@ function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { commitRoot( root, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate ); } else { if ( @@ -23801,6 +23861,7 @@ function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ), msUntilTimeout @@ -23814,6 +23875,7 @@ function finishConcurrentRender(root, exitStatus, finishedWork, lanes) { finishedWork, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ); } @@ -23824,6 +23886,7 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes ) { // TODO: Combine retry throttling with Suspensey commits. Right now they run @@ -23847,14 +23910,20 @@ function commitRootWhenReady( // 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); return; } } // Otherwise, commit immediately. - commitRoot(root, recoverableErrors, transitions); + commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate); } function isRenderConsistentWithExternalStores(finishedWork) { @@ -23917,18 +23986,49 @@ function isRenderConsistentWithExternalStores(finishedWork) { // 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); // Check for recursive updates + + if (executionContext & RenderContext) { + workInProgressRootDidIncludeRecursiveRenderUpdate = true; + } else if (executionContext & CommitContext) { + didIncludeCommitPhaseUpdate = true; + } + + throwIfInfiniteUpdateLoopDetected(); +} + +function markRootPinged(root, pingedLanes) { + markRootPinged$1(root, pingedLanes); // 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) { // 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); suspendedLanes = removeLanes( suspendedLanes, workInProgressRootInterleavedUpdatedLanes ); + markRootSuspended$1(root, suspendedLanes); } // This is the entry point for synchronous tasks that don't go // through Scheduler @@ -23999,7 +24099,8 @@ function performSyncWorkOnRoot(root) { commitRoot( root, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate ); // Before exiting, make sure there's a callback scheduled for the next // pending level. @@ -24140,6 +24241,7 @@ function prepareFreshStack(root, lanes) { workInProgressRootPingedLanes = NoLanes; workInProgressRootConcurrentErrors = null; workInProgressRootRecoverableErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = false; finishQueueingConcurrentUpdates(); { @@ -25100,7 +25202,12 @@ function unwindUnitOfWork(unitOfWork) { workInProgress = null; } -function commitRoot(root, recoverableErrors, transitions) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate +) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -25113,6 +25220,7 @@ function commitRoot(root, recoverableErrors, transitions) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority ); } finally { @@ -25127,6 +25235,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel ) { do { @@ -25190,7 +25299,9 @@ function commitRootImpl( var concurrentlyUpdatedLanes = getConcurrentlyUpdatedLanes(); remainingLanes = mergeLanes(remainingLanes, concurrentlyUpdatedLanes); - markRootFinished(root, remainingLanes); + markRootFinished(root, remainingLanes); // 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. @@ -25373,7 +25484,18 @@ function commitRootImpl( remainingLanes = root.pendingLanes; - if (includesSyncLane(remainingLanes)) { + 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. + didIncludeCommitPhaseUpdate || + didIncludeRenderPhaseUpdate || // As an additional precaution, we also check if there's any remaining sync + // work. Theoretically this should be unreachable but if there's a mistake + // in React it helps to be overly defensive given how hard it is to debug + // those scenarios otherwise. This won't catch recursive async updates, + // though, which is why we check the flags above first. + includesSyncLane(remainingLanes) + ) { { markNestedUpdateScheduled(); } // Count the number of times the root synchronously re-renders without @@ -25798,6 +25920,18 @@ function throwIfInfiniteUpdateLoopDetected() { nestedPassiveUpdateCount = 0; rootWithNestedUpdates = null; rootWithPassiveNestedUpdates = null; + + 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 " + @@ -27410,7 +27544,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.3.0-canary-7ee9ca02"; +var ReactVersion = "18.3.0-canary-5cc0237b"; function createPortal$1( children, diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index a1c79d6bb779d..b0e7cf51dea71 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<43dea1f462c798a7ba8b2fa96322addc>> + * @generated SignedSource<<18df9746b30e120b7e211c453d1224d6>> */ "use strict"; @@ -1891,11 +1891,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -2204,14 +2199,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 1073741824)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -3435,10 +3423,23 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { var workInProgressRoot$jscomp$0 = workInProgressRoot, workInProgressRootRenderLanes$jscomp$0 = workInProgressRootRenderLanes, + nestedUpdatePasses = 0, errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; + if (60 < ++nestedUpdatePasses) { + for (onlyLegacy = firstScheduledRoot; null !== onlyLegacy; ) + (workInProgressRoot$jscomp$0 = onlyLegacy.next), + (onlyLegacy.next = null), + (onlyLegacy = workInProgressRoot$jscomp$0); + firstScheduledRoot = lastScheduledRoot = null; + onlyLegacy = Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ); + null === errors ? (errors = [onlyLegacy]) : errors.push(onlyLegacy); + break; + } for (var root = firstScheduledRoot; null !== root; ) { if ( (!onlyLegacy || 0 === root.tag) && @@ -3490,7 +3491,8 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { commitRoot( root$jscomp$0, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate )); } ensureRootIsScheduled(root$jscomp$0); @@ -7663,6 +7665,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressRootPingedLanes = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -7815,6 +7819,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ), exitStatus @@ -7826,6 +7831,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ); } @@ -7875,10 +7881,11 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes ) { 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); - commitRoot(root, recoverableErrors, transitions); + commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -7914,6 +7921,15 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 536870912 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); +} function markRootSuspended(root, suspendedLanes) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -7967,6 +7983,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; finishQueueingConcurrentUpdates(); return root; } @@ -8438,7 +8455,12 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig.transition; try { @@ -8448,6 +8470,7 @@ function commitRoot(root, recoverableErrors, transitions) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority ); } finally { @@ -8460,6 +8483,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel ) { do flushPassiveEffects(); @@ -8481,6 +8505,7 @@ function commitRootImpl( var remainingLanes = transitions.lanes | transitions.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -8541,6 +8566,8 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; + didIncludeCommitPhaseUpdate || + didIncludeRenderPhaseUpdate || 0 !== (remainingLanes & 3) ? root === rootWithNestedUpdates ? nestedUpdateCount++ @@ -8656,6 +8683,10 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -8703,6 +8734,20 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -9661,10 +9706,10 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1097 = { + devToolsConfig$jscomp$inline_1102 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "18.3.0-canary-9b5515c1", + version: "18.3.0-canary-6d6b834e", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -9680,11 +9725,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1353 = { - bundleType: devToolsConfig$jscomp$inline_1097.bundleType, - version: devToolsConfig$jscomp$inline_1097.version, - rendererPackageName: devToolsConfig$jscomp$inline_1097.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1097.rendererConfig, +var internals$jscomp$inline_1361 = { + bundleType: devToolsConfig$jscomp$inline_1102.bundleType, + version: devToolsConfig$jscomp$inline_1102.version, + rendererPackageName: devToolsConfig$jscomp$inline_1102.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1102.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -9700,26 +9745,26 @@ var internals$jscomp$inline_1353 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1097.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1102.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-9b5515c1" + reconcilerVersion: "18.3.0-canary-6d6b834e" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1354 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1362 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1354.isDisabled && - hook$jscomp$inline_1354.supportsFiber + !hook$jscomp$inline_1362.isDisabled && + hook$jscomp$inline_1362.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1354.inject( - internals$jscomp$inline_1353 + (rendererID = hook$jscomp$inline_1362.inject( + internals$jscomp$inline_1361 )), - (injectedHook = hook$jscomp$inline_1354); + (injectedHook = hook$jscomp$inline_1362); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 641a99a8010c1..deca9ca86d5fd 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<752421d40b30109c7cbe8342b2cc683c>> + * @generated SignedSource<> */ @@ -1989,11 +1989,6 @@ function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; } -function markRootUpdated(root, updateLane) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; @@ -2332,14 +2327,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) { (update.lane = lane | 1073741824)); } function getRootForUpdatedFiber(sourceFiber) { - if (50 < nestedUpdateCount) - throw ( - ((nestedUpdateCount = 0), - (rootWithNestedUpdates = null), - Error( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." - )) - ); + throwIfInfiniteUpdateLoopDetected(); for (var parent = sourceFiber.return; null !== parent; ) (sourceFiber = parent), (parent = sourceFiber.return); return 3 === sourceFiber.tag ? sourceFiber.stateNode : null; @@ -3563,10 +3551,23 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { if (!isFlushingWork && mightHavePendingSyncWork) { var workInProgressRoot$jscomp$0 = workInProgressRoot, workInProgressRootRenderLanes$jscomp$0 = workInProgressRootRenderLanes, + nestedUpdatePasses = 0, errors = null; isFlushingWork = !0; do { var didPerformSomeWork = !1; + if (60 < ++nestedUpdatePasses) { + for (onlyLegacy = firstScheduledRoot; null !== onlyLegacy; ) + (workInProgressRoot$jscomp$0 = onlyLegacy.next), + (onlyLegacy.next = null), + (onlyLegacy = workInProgressRoot$jscomp$0); + firstScheduledRoot = lastScheduledRoot = null; + onlyLegacy = Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ); + null === errors ? (errors = [onlyLegacy]) : errors.push(onlyLegacy); + break; + } for (var root = firstScheduledRoot; null !== root; ) { if ( (!onlyLegacy || 0 === root.tag) && @@ -3620,7 +3621,8 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) { commitRoot( root$jscomp$0, workInProgressRootRecoverableErrors, - workInProgressTransitions + workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate )); } ensureRootIsScheduled(root$jscomp$0); @@ -8191,6 +8193,8 @@ var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map, workInProgressRootPingedLanes = 0, workInProgressRootConcurrentErrors = null, workInProgressRootRecoverableErrors = null, + workInProgressRootDidIncludeRecursiveRenderUpdate = !1, + didIncludeCommitPhaseUpdate = !1, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, workInProgressTransitions = null, @@ -8346,6 +8350,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ), exitStatus @@ -8357,6 +8362,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { didTimeout, workInProgressRootRecoverableErrors, workInProgressTransitions, + workInProgressRootDidIncludeRecursiveRenderUpdate, lanes ); } @@ -8406,10 +8412,11 @@ function commitRootWhenReady( finishedWork, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, lanes ) { 0 === (lanes & 42) && accumulateSuspenseyCommitOnFiber(finishedWork); - commitRoot(root, recoverableErrors, transitions); + commitRoot(root, recoverableErrors, transitions, didIncludeRenderPhaseUpdate); } function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { @@ -8445,6 +8452,15 @@ function isRenderConsistentWithExternalStores(finishedWork) { } return !0; } +function markRootUpdated(root, updatedLanes) { + root.pendingLanes |= updatedLanes; + 536870912 !== updatedLanes && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); +} function markRootSuspended(root, suspendedLanes) { suspendedLanes &= ~workInProgressRootPingedLanes; suspendedLanes &= ~workInProgressRootInterleavedUpdatedLanes; @@ -8498,6 +8514,7 @@ function prepareFreshStack(root, lanes) { 0; workInProgressRootRecoverableErrors = workInProgressRootConcurrentErrors = null; + workInProgressRootDidIncludeRecursiveRenderUpdate = !1; finishQueueingConcurrentUpdates(); return root; } @@ -9046,7 +9063,12 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors, transitions) { +function commitRoot( + root, + recoverableErrors, + transitions, + didIncludeRenderPhaseUpdate +) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig.transition; try { @@ -9056,6 +9078,7 @@ function commitRoot(root, recoverableErrors, transitions) { root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, previousUpdateLanePriority ); } finally { @@ -9068,6 +9091,7 @@ function commitRootImpl( root, recoverableErrors, transitions, + didIncludeRenderPhaseUpdate, renderPriorityLevel ) { do flushPassiveEffects(); @@ -9092,6 +9116,7 @@ function commitRootImpl( var remainingLanes = transitions.lanes | transitions.childLanes; remainingLanes |= concurrentlyUpdatedLanes; markRootFinished(root, remainingLanes); + didIncludeCommitPhaseUpdate = !1; root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); @@ -9160,6 +9185,8 @@ function commitRootImpl( 0 !== root.tag && flushPassiveEffects(); remainingLanes = root.pendingLanes; + didIncludeCommitPhaseUpdate || + didIncludeRenderPhaseUpdate || 0 !== (remainingLanes & 3) ? ((nestedUpdateScheduled = !0), root === rootWithNestedUpdates @@ -9332,6 +9359,10 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(wakeable); root.pingedLanes |= root.suspendedLanes & pingedLanes; + executionContext & 2 + ? (workInProgressRootDidIncludeRecursiveRenderUpdate = !0) + : executionContext & 4 && (didIncludeCommitPhaseUpdate = !0); + throwIfInfiniteUpdateLoopDetected(); workInProgressRoot === root && (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || @@ -9379,6 +9410,20 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); retryTimedOutBoundary(boundaryFiber, retryLane); } +function throwIfInfiniteUpdateLoopDetected() { + if (50 < nestedUpdateCount) + throw ( + ((nestedUpdateCount = 0), + (rootWithNestedUpdates = null), + executionContext & 2 && + null !== workInProgressRoot && + (workInProgressRoot.errorRecoveryDisabledLanes |= + workInProgressRootRenderLanes), + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + )) + ); +} var beginWork; beginWork = function (current, workInProgress, renderLanes) { if (null !== current) @@ -10370,10 +10415,10 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1175 = { + devToolsConfig$jscomp$inline_1180 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "18.3.0-canary-355ac2fb", + version: "18.3.0-canary-072c2160", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10403,10 +10448,10 @@ var roots = new Map(), } catch (err) {} return hook.checkDCE ? !0 : !1; })({ - bundleType: devToolsConfig$jscomp$inline_1175.bundleType, - version: devToolsConfig$jscomp$inline_1175.version, - rendererPackageName: devToolsConfig$jscomp$inline_1175.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1175.rendererConfig, + bundleType: devToolsConfig$jscomp$inline_1180.bundleType, + version: devToolsConfig$jscomp$inline_1180.version, + rendererPackageName: devToolsConfig$jscomp$inline_1180.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1180.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -10422,14 +10467,14 @@ var roots = new Map(), return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1175.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1180.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-355ac2fb" + reconcilerVersion: "18.3.0-canary-072c2160" }); exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { computeComponentStackForErrorReporting: function (reactTag) {