From 118cf689142d6754a300d714caf33b4fd64b575d Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Mon, 6 Jun 2022 10:58:29 -0700 Subject: [PATCH] React Native sync for revisions bd4784c...d300ceb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This sync includes the following changes: - **[dd4950c90](https://github.com/facebook/react/commit/dd4950c90 )**: [Flight] Implement useId hook ([#24172](https://github.com/facebook/react/pull/24172)) //// - **[26a5b3c7f](https://github.com/facebook/react/commit/26a5b3c7f )**: Explicitly set `highWaterMark` to 0 for `ReadableStream` ([#24641](https://github.com/facebook/react/pull/24641)) //// - **[aec575914](https://github.com/facebook/react/commit/aec575914 )**: [Fizz] Send errors down to client ([#24551](https://github.com/facebook/react/pull/24551)) //// - **[a2766387e](https://github.com/facebook/react/commit/a2766387e )**: [Fizz] Improve text separator byte efficiency ([#24630](https://github.com/facebook/react/pull/24630)) //// - **[f7860538a](https://github.com/facebook/react/commit/f7860538a )**: Fix typo in useSyncExternalStore main entry point error ([#24631](https://github.com/facebook/react/pull/24631)) //// - **[1bed20731](https://github.com/facebook/react/commit/1bed20731 )**: Add a module map option to the Webpack Flight Client ([#24629](https://github.com/facebook/react/pull/24629)) //// - **[b2763d3ea](https://github.com/facebook/react/commit/b2763d3ea )**: Move hydration code out of normal Suspense path ([#24532](https://github.com/facebook/react/pull/24532)) //// - **[357a61324](https://github.com/facebook/react/commit/357a61324 )**: [DevTools][Transition Tracing] Added support for Suspense Boundaries ([#23365](https://github.com/facebook/react/pull/23365)) //// - **[2c8a1452b](https://github.com/facebook/react/commit/2c8a1452b )**: Fix ignored setState in Safari when iframe is touched ([#24459](https://github.com/facebook/react/pull/24459)) //// - **[62662633d](https://github.com/facebook/react/commit/62662633d )**: Remove enableFlipOffscreenUnhideOrder ([#24545](https://github.com/facebook/react/pull/24545)) //// - **[34da5aa69](https://github.com/facebook/react/commit/34da5aa69 )**: Only treat updates to lazy as a new mount in legacy mode ([#24530](https://github.com/facebook/react/pull/24530)) //// - **[46a6d77e3](https://github.com/facebook/react/commit/46a6d77e3 )**: Unify JSResourceReference Interfaces ([#24507](https://github.com/facebook/react/pull/24507)) //// - **[6cbf0f7fa](https://github.com/facebook/react/commit/6cbf0f7fa )**: Fork ReactSymbols ([#24484](https://github.com/facebook/react/pull/24484)) //// - **[a10a9a6b5](https://github.com/facebook/react/commit/a10a9a6b5 )**: Add test for hiding children after layout destroy ([#24483](https://github.com/facebook/react/pull/24483)) //// - **[b4eb0ad71](https://github.com/facebook/react/commit/b4eb0ad71 )**: Do not replay erroring beginWork with invokeGuardedCallback when suspended or previously errored ([#24480](https://github.com/facebook/react/pull/24480)) //// - **[99eef9e2d](https://github.com/facebook/react/commit/99eef9e2d )**: Hide children of Offscreen after destroy effects ([#24446](https://github.com/facebook/react/pull/24446)) //// - **[ce1386028](https://github.com/facebook/react/commit/ce1386028 )**: Remove enablePersistentOffscreenHostContainer flag ([#24460](https://github.com/facebook/react/pull/24460)) //// - **[72b7462fe](https://github.com/facebook/react/commit/72b7462fe )**: Bump local package.json versions for 18.1 release ([#24447](https://github.com/facebook/react/pull/24447)) //// - **[22edb9f77](https://github.com/facebook/react/commit/22edb9f77 )**: React `version` field should match package.json ([#24445](https://github.com/facebook/react/pull/24445)) //// - **[6bf3deef5](https://github.com/facebook/react/commit/6bf3deef5 )**: Upgrade react-shallow-renderer to support react 18 ([#24442](https://github.com/facebook/react/pull/24442)) //// Changelog: [General][Changed] - React Native sync for revisions bd4784c...d300ceb jest_e2e[run_all_tests] Reviewed By: cortinico, kacieb Differential Revision: D36874368 fbshipit-source-id: c0ee015f4ef2fa56e57f7a1f6bc37dd05c949877 --- BUCK | 1 - Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.js | 4328 ++++++++++------- .../implementations/ReactFabric-prod.js | 2404 +++++---- .../implementations/ReactFabric-profiling.js | 2634 +++++----- .../ReactNativeRenderer-dev.js | 4219 +++++++++------- .../ReactNativeRenderer-prod.js | 2644 +++++----- .../ReactNativeRenderer-profiling.js | 2877 ++++++----- package.json | 10 +- packages/rn-tester/package.json | 2 +- repo-config/package.json | 4 +- template/package.json | 4 +- yarn.lock | 56 +- 13 files changed, 11104 insertions(+), 8081 deletions(-) diff --git a/BUCK b/BUCK index a42859addf9..e43a573088b 100644 --- a/BUCK +++ b/BUCK @@ -763,7 +763,6 @@ rn_library( "//xplat/js:node_modules__use_19sync_19external_19store", "//xplat/js:node_modules__whatwg_19fetch", "//xplat/js/RKJSModules/Libraries/Polyfills:Polyfills", - "//xplat/js/RKJSModules/Libraries/React:React", "//xplat/js/RKJSModules/vendor/react:react", "//xplat/js/RKJSModules/vendor/react-test-renderer:react-test-renderer", "//xplat/js/RKJSModules/vendor/scheduler:scheduler", diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index a9f8463f056..c9a2a7c8e0a 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -bd4784c8f8c6b17cf45c712db8ed8ed19a622b26 \ No newline at end of file +d300cebde2a63e742ccb8b6aa7b0f61db1ae29b4 \ No newline at end of file diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.js b/Libraries/Renderer/implementations/ReactFabric-dev.js index af858df2513..89b2d115311 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactFabric-dev * @preventMunge - * @generated SignedSource<<1905bf58c5e02827f73cc582ec7db91b>> + * @generated SignedSource<> */ 'use strict'; @@ -2776,7 +2776,6 @@ function set(key, value) { var enableSchedulingProfiler = false; var enableProfilerTimer = true; var enableProfilerCommitHooks = true; -var enableLazyElements = false; var warnAboutStringRefs = false; var enableSuspenseAvoidThisFallback = false; var enableNewReconciler = false; @@ -3039,9 +3038,6 @@ var Placement = var Update = /* */ 4; -var PlacementAndUpdate = - /* */ - Placement | Update; var ChildDeletion = /* */ 16; @@ -3069,9 +3065,6 @@ var Passive = var Hydrating = /* */ 4096; -var HydratingAndUpdate = - /* */ - Hydrating | Update; var Visibility = /* */ 8192; @@ -4302,13 +4295,13 @@ var InputContinuousHydrationLane = /* */ 2; var InputContinuousLane = - /* */ + /* */ 4; var DefaultHydrationLane = /* */ 8; var DefaultLane = - /* */ + /* */ 16; var TransitionHydrationLane = /* */ @@ -4387,13 +4380,13 @@ var SelectiveHydrationLane = /* */ 134217728; var NonIdleLanes = - /* */ + /* */ 268435455; var IdleHydrationLane = /* */ 268435456; var IdleLane = - /* */ + /* */ 536870912; var OffscreenLane = /* */ @@ -4726,6 +4719,10 @@ function includesNonIdleWork(lanes) { function includesOnlyRetries(lanes) { return (lanes & RetryLanes) === lanes; } +function includesOnlyNonUrgentLanes(lanes) { + var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane; + return (lanes & UrgentLanes) === NoLanes; +} function includesOnlyTransitions(lanes) { return (lanes & TransitionLanes) === lanes; } @@ -4743,7 +4740,7 @@ function includesExpiredLane(root, lanes) { return (lanes & root.expiredLanes) !== NoLanes; } function isTransitionLane(lane) { - return (lane & TransitionLanes) !== 0; + return (lane & TransitionLanes) !== NoLanes; } function claimNextTransitionLane() { // Cycle through the lanes, assigning each new transition to the next lane. @@ -4752,7 +4749,7 @@ function claimNextTransitionLane() { var lane = nextTransitionLane; nextTransitionLane <<= 1; - if ((nextTransitionLane & TransitionLanes) === 0) { + if ((nextTransitionLane & TransitionLanes) === NoLanes) { nextTransitionLane = TransitionLane1; } @@ -4762,7 +4759,7 @@ function claimNextRetryLane() { var lane = nextRetryLane; nextRetryLane <<= 1; - if ((nextRetryLane & RetryLanes) === 0) { + if ((nextRetryLane & RetryLanes) === NoLanes) { nextRetryLane = RetryLane1; } @@ -4864,8 +4861,8 @@ function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; // Let's try everything again - root.suspendedLanes = 0; - root.pingedLanes = 0; + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; root.expiredLanes &= remainingLanes; root.mutableReadLanes &= remainingLanes; root.entangledLanes &= remainingLanes; @@ -4915,6 +4912,63 @@ function markRootEntangled(root, entangledLanes) { lanes &= ~lane; } } +function getBumpedLaneForHydration(root, renderLanes) { + var renderLane = getHighestPriorityLane(renderLanes); + var lane; + + switch (renderLane) { + case InputContinuousLane: + lane = InputContinuousHydrationLane; + break; + + case DefaultLane: + lane = DefaultHydrationLane; + break; + + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + case TransitionLane15: + case TransitionLane16: + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + case RetryLane5: + lane = TransitionHydrationLane; + break; + + case IdleLane: + lane = IdleHydrationLane; + break; + + default: + // Everything else is already either a hydration lane, or shouldn't + // be retried at a hydration lane. + lane = NoLane; + break; + } // Check if the lane we chose is suspended. If so, that indicates that we + // already attempted and failed to hydrate at that level. Also check if we're + // already rendering that lane, which is rare but could happen. + + if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) { + // Give up trying to hydrate and fall back to client render. + return NoLane; + } + + return lane; +} function addFiberToLanesMap(root, fiber, lanes) { if (!isDevToolsPresent) { return; @@ -4957,6 +5011,11 @@ function movePendingFibersToMemoized(root, lanes) { lanes &= ~lane; } } +function getTransitionsForLanes(root, lanes) { + { + return null; + } +} var DiscreteEventPriority = SyncLane; var ContinuousEventPriority = InputContinuousLane; @@ -5005,8 +5064,6 @@ function shim() { "Please file an issue." ); } // Mutation (when unsupported) - -var supportsMutation = false; var commitMount = shim; // Renderers that don't support hydration @@ -5020,6 +5077,8 @@ function shim$1() { } // Hydration (when unsupported) var isSuspenseInstancePending = shim$1; var isSuspenseInstanceFallback = shim$1; +var getSuspenseInstanceFallbackErrorDetails = shim$1; +var registerSuspenseInstanceRetry = shim$1; var hydrateTextInstance = shim$1; var errorHydratingContainer = shim$1; @@ -5429,7 +5488,7 @@ function cloneInstance( node: clone, canonical: instance.canonical }; -} // TODO: These two methods should be replaced with `createOffscreenInstance` and +} function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { var viewConfig = instance.canonical.viewConfig; var node = instance.node; @@ -5458,6 +5517,7 @@ function appendChildToContainerChildSet(childSet, child) { function finalizeContainerChildren(container, newChildren) { completeRoot(container, newChildren); } +function replaceContainerChildren(container, newChildren) {} function preparePortalMount(portalInstance) { // noop } @@ -6101,6 +6161,125 @@ function isRootDehydrated(root) { return currentState.isDehydrated; } +// TODO: Use the unified fiber stack module instead of this local one? +// Intentionally not using it yet to derisk the initial implementation, because +// the way we push/pop these values is a bit unusual. If there's a mistake, I'd +// rather the ids be wrong than crash the whole reconciler. +var forkStack = []; +var forkStackIndex = 0; +var treeForkProvider = null; +var treeForkCount = 0; +var idStack = []; +var idStackIndex = 0; +var treeContextProvider = null; +var treeContextId = 1; +var treeContextOverflow = ""; + +function popTreeContext(workInProgress) { + // Restore the previous values. + // This is a bit more complicated than other context-like modules in Fiber + // because the same Fiber may appear on the stack multiple times and for + // different reasons. We have to keep popping until the work-in-progress is + // no longer at the top of the stack. + while (workInProgress === treeForkProvider) { + treeForkProvider = forkStack[--forkStackIndex]; + forkStack[forkStackIndex] = null; + treeForkCount = forkStack[--forkStackIndex]; + forkStack[forkStackIndex] = null; + } + + while (workInProgress === treeContextProvider) { + treeContextProvider = idStack[--idStackIndex]; + idStack[idStackIndex] = null; + treeContextOverflow = idStack[--idStackIndex]; + idStack[idStackIndex] = null; + treeContextId = idStack[--idStackIndex]; + idStack[idStackIndex] = null; + } +} + +var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches +// due to earlier mismatches or a suspended fiber. + +var didSuspendOrErrorDEV = false; // Hydration errors that were thrown inside this boundary + +var hydrationErrors = null; +function didSuspendOrErrorWhileHydratingDEV() { + { + return didSuspendOrErrorDEV; + } +} + +function reenterHydrationStateFromDehydratedSuspenseInstance( + fiber, + suspenseInstance, + treeContext +) { + { + return false; + } +} + +function prepareToHydrateHostInstance( + fiber, + rootContainerInstance, + hostContext +) { + { + throw new Error( + "Expected prepareToHydrateHostInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } +} + +function prepareToHydrateHostTextInstance(fiber) { + { + throw new Error( + "Expected prepareToHydrateHostTextInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + var shouldUpdate = hydrateTextInstance(); +} + +function prepareToHydrateHostSuspenseInstance(fiber) { + { + throw new Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } +} + +function popHydrationState(fiber) { + { + return false; + } +} + +function upgradeHydrationErrorsToRecoverable() { + if (hydrationErrors !== null) { + // Successfully completed a forced client render. The errors that occurred + // during the hydration attempt are now recovered. We will log them in + // commit phase, once the entire tree has finished. + queueRecoverableErrors(hydrationErrors); + hydrationErrors = null; + } +} + +function getIsHydrating() { + return isHydrating; +} + +function queueHydrationError(error) { + if (hydrationErrors === null) { + hydrationErrors = [error]; + } else { + hydrationErrors.push(error); + } +} + var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = null; function requestCurrentTransition() { @@ -6236,11 +6415,17 @@ function resetCurrentFiber() { } function setCurrentFiber(fiber) { { - ReactDebugCurrentFrame$1.getCurrentStack = getCurrentFiberStackInDev; + ReactDebugCurrentFrame$1.getCurrentStack = + fiber === null ? null : getCurrentFiberStackInDev; current = fiber; isRendering = false; } } +function getCurrentFiber() { + { + return current; + } +} function setIsRendering(rendering) { { isRendering = rendering; @@ -6880,6 +7065,34 @@ function propagateContextChange_eager(workInProgress, context, renderLanes) { } else if (fiber.tag === ContextProvider) { // Don't scan deeper if this is a matching provider nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + } else if (fiber.tag === DehydratedFragment) { + // If a dehydrated suspense boundary is in this subtree, we don't know + // if it will have any context consumers in it. The best we can do is + // mark it as having updates. + var parentSuspense = fiber.return; + + if (parentSuspense === null) { + throw new Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + } + + parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes); + var _alternate = parentSuspense.alternate; + + if (_alternate !== null) { + _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes); + } // This is intentionally passing this fiber as the parent + // because we want to schedule this fiber as having work + // on its children. We'll use the childLanes on + // this fiber to indicate that a context has changed. + + scheduleContextWorkOnParentPath( + parentSuspense, + renderLanes, + workInProgress + ); + nextFiber = fiber.sibling; } else { // Traverse down. nextFiber = fiber.child; @@ -6996,6 +7209,9 @@ function pushInterleavedQueue(queue) { interleavedQueues.push(queue); } } +function hasInterleavedUpdates() { + return interleavedQueues !== null; +} function enqueueInterleavedUpdates() { // Transfer the interleaved updates onto the main queue. Each queue has a // `pending` field and an `interleaved` field. When they are not null, they @@ -8619,78 +8835,6 @@ function updateClassInstance( return shouldUpdate; } -// TODO: Use the unified fiber stack module instead of this local one? -// Intentionally not using it yet to derisk the initial implementation, because -// the way we push/pop these values is a bit unusual. If there's a mistake, I'd -// rather the ids be wrong than crash the whole reconciler. -var forkStack = []; -var forkStackIndex = 0; -var treeForkProvider = null; -var treeForkCount = 0; -var idStack = []; -var idStackIndex = 0; -var treeContextProvider = null; -var treeContextId = 1; -var treeContextOverflow = ""; - -function popTreeContext(workInProgress) { - // Restore the previous values. - // This is a bit more complicated than other context-like modules in Fiber - // because the same Fiber may appear on the stack multiple times and for - // different reasons. We have to keep popping until the work-in-progress is - // no longer at the top of the stack. - while (workInProgress === treeForkProvider) { - treeForkProvider = forkStack[--forkStackIndex]; - forkStack[forkStackIndex] = null; - treeForkCount = forkStack[--forkStackIndex]; - forkStack[forkStackIndex] = null; - } - - while (workInProgress === treeContextProvider) { - treeContextProvider = idStack[--idStackIndex]; - idStack[idStackIndex] = null; - treeContextOverflow = idStack[--idStackIndex]; - idStack[idStackIndex] = null; - treeContextId = idStack[--idStackIndex]; - idStack[idStackIndex] = null; - } -} - -var isHydrating = false; - -function prepareToHydrateHostInstance( - fiber, - rootContainerInstance, - hostContext -) { - { - throw new Error( - "Expected prepareToHydrateHostInstance() to never be called. " + - "This error is likely caused by a bug in React. Please file an issue." - ); - } -} - -function prepareToHydrateHostTextInstance(fiber) { - { - throw new Error( - "Expected prepareToHydrateHostTextInstance() to never be called. " + - "This error is likely caused by a bug in React. Please file an issue." - ); - } - var shouldUpdate = hydrateTextInstance(); -} - -function popHydrationState(fiber) { - { - return false; - } -} - -function getIsHydrating() { - return isHydrating; -} - var didWarnAboutMaps; var didWarnAboutGenerators; var didWarnAboutStringRefs; @@ -8903,6 +9047,12 @@ function warnOnFunctionType(returnFiber) { ); } } + +function resolveLazy(lazyType) { + var payload = lazyType._payload; + var init = lazyType._init; + return init(payload); +} // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. @@ -9044,7 +9194,10 @@ function ChildReconciler(shouldTrackSideEffects) { // We need to do this after the Hot Reloading check above, // because hot reloading has different semantics than prod because // it doesn't resuspend. So we can't let the call below suspend. - enableLazyElements + (typeof elementType === "object" && + elementType !== null && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === current.type) ) { // Move based on index var existing = useFiber(current, element.props); @@ -9141,6 +9294,12 @@ function ChildReconciler(shouldTrackSideEffects) { _created2.return = returnFiber; return _created2; } + + case REACT_LAZY_TYPE: { + var payload = newChild._payload; + var init = newChild._init; + return createChild(returnFiber, init(payload), lanes); + } } if (isArray(newChild) || getIteratorFn(newChild)) { @@ -9202,6 +9361,12 @@ function ChildReconciler(shouldTrackSideEffects) { return null; } } + + case REACT_LAZY_TYPE: { + var payload = newChild._payload; + var init = newChild._init; + return updateSlot(returnFiber, oldFiber, init(payload), lanes); + } } if (isArray(newChild) || getIteratorFn(newChild)) { @@ -9260,6 +9425,17 @@ function ChildReconciler(shouldTrackSideEffects) { return updatePortal(returnFiber, _matchedFiber2, newChild, lanes); } + + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + init(payload), + lanes + ); } if (isArray(newChild) || getIteratorFn(newChild)) { @@ -9326,6 +9502,12 @@ function ChildReconciler(shouldTrackSideEffects) { ); break; + + case REACT_LAZY_TYPE: + var payload = child._payload; + var init = child._init; + warnOnInvalidKey(init(payload), knownKeys, returnFiber); + break; } } @@ -9767,7 +9949,10 @@ function ChildReconciler(shouldTrackSideEffects) { // We need to do this after the Hot Reloading check above, // because hot reloading has different semantics than prod because // it doesn't resuspend. So we can't let the call below suspend. - enableLazyElements + (typeof elementType === "object" && + elementType !== null && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === child.type) ) { deleteRemainingChildren(returnFiber, child.sibling); @@ -9896,6 +10081,17 @@ function ChildReconciler(shouldTrackSideEffects) { lanes ) ); + + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; // TODO: This function is supposed to be non-recursive. + + return reconcileChildFibers( + returnFiber, + currentFirstChild, + init(payload), + lanes + ); } if (isArray(newChild)) { @@ -11415,66 +11611,72 @@ function updateMemo(nextCreate, deps) { } function mountDeferredValue(value) { - var _mountState = mountState(value), - prevValue = _mountState[0], - setValue = _mountState[1]; - - mountEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = mountWorkInProgressHook(); + hook.memoizedState = value; + return value; } function updateDeferredValue(value) { - var _updateState = updateState(), - prevValue = _updateState[0], - setValue = _updateState[1]; - - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + var resolvedCurrentHook = currentHook; + var prevValue = resolvedCurrentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value); } function rerenderDeferredValue(value) { - var _rerenderState = rerenderState(), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; + var hook = updateWorkInProgressHook(); - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; + if (currentHook === null) { + // This is a rerender during a mount. + hook.memoizedState = value; + return value; + } else { + // This is a rerender during an update. + var prevValue = currentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value); + } +} - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; +function updateDeferredValueImpl(hook, prevValue, value) { + var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes); + + if (shouldDeferValue) { + // This is an urgent update. If the value has changed, keep using the + // previous value and spawn a deferred render to update it later. + if (!objectIs(value, prevValue)) { + // Schedule a deferred render + var deferredLane = claimNextTransitionLane(); + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + deferredLane + ); + markSkippedUpdateLanes(deferredLane); // Set this to true to indicate that the rendered value is inconsistent + // from the latest value. The name "baseState" doesn't really match how we + // use it because we're reusing a state hook field instead of creating a + // new one. + + hook.baseState = true; + } // Reuse the previous value + + return prevValue; + } else { + // This is not an urgent update, so we can use the latest value regardless + // of what it is. No need to defer it. + // However, if we're currently inside a spawned render, then we need to mark + // this as an update to prevent the fiber from bailing out. + // + // `baseState` is true when the current value is different from the rendered + // value. The name doesn't really match how we use it because we're reusing + // a state hook field instead of creating a new one. + if (hook.baseState) { + // Flip this back to false. + hook.baseState = false; + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = value; + return value; + } } function startTransition(setPending, callback, options) { @@ -11517,9 +11719,9 @@ function startTransition(setPending, callback, options) { } function mountTransition() { - var _mountState2 = mountState(false), - isPending = _mountState2[0], - setPending = _mountState2[1]; // The `start` method never changes. + var _mountState = mountState(false), + isPending = _mountState[0], + setPending = _mountState[1]; // The `start` method never changes. var start = startTransition.bind(null, setPending); var hook = mountWorkInProgressHook(); @@ -11528,8 +11730,8 @@ function mountTransition() { } function updateTransition() { - var _updateState2 = updateState(), - isPending = _updateState2[0]; + var _updateState = updateState(), + isPending = _updateState[0]; var hook = updateWorkInProgressHook(); var start = hook.memoizedState; @@ -11537,8 +11739,8 @@ function updateTransition() { } function rerenderTransition() { - var _rerenderState2 = rerenderState(), - isPending = _rerenderState2[0]; + var _rerenderState = rerenderState(), + isPending = _rerenderState[0]; var hook = updateWorkInProgressHook(); var start = hook.memoizedState; @@ -13348,1052 +13550,6 @@ function getSuspendedCache() { } // This function is called when a Suspense boundary suspends. It returns the } -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; -} - -function markRef(workInProgress) { - workInProgress.flags |= Ref; -} - -function hadNoMutationsEffects(current, completedWork) { - var didBailout = current !== null && current.child === completedWork.child; - - if (didBailout) { - return true; - } - - if ((completedWork.flags & ChildDeletion) !== NoFlags) { - return false; - } // TODO: If we move the `hadNoMutationsEffects` call after `bubbleProperties` - // then we only have to check the `completedWork.subtreeFlags`. - - var child = completedWork.child; - - while (child !== null) { - if ( - (child.flags & MutationMask) !== NoFlags || - (child.subtreeFlags & MutationMask) !== NoFlags - ) { - return false; - } - - child = child.sibling; - } - - return true; -} - -var appendAllChildren; -var updateHostContainer; -var updateHostComponent; -var updateHostText; - -{ - // Persistent host tree mode - appendAllChildren = function( - parent, - workInProgress, - needsVisibilityToggle, - isHidden - ) { - // We only have the top Fiber that was created but we need recurse down its - // children to find all the terminal nodes. - var node = workInProgress.child; - - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; - - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); - } - - appendInitialChild(parent, instance); - } else if (node.tag === HostText) { - var _instance = node.stateNode; - - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance = cloneHiddenTextInstance(); - } - - appendInitialChild(parent, _instance); - } else if (node.tag === HostPortal); - else if (node.tag === OffscreenComponent && node.memoizedState !== null) { - // The children in this boundary are hidden. Toggle their visibility - // before appending. - var child = node.child; - - if (child !== null) { - child.return = node; - } - - { - appendAllChildren(parent, node, true, true); - } - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } // $FlowFixMe This is correct but Flow is confused by the labeled break. - - node = node; - - if (node === workInProgress) { - return; - } - - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } - - node = node.return; - } - - node.sibling.return = node.return; - node = node.sibling; - } - }; // An unfortunate fork of appendAllChildren because we have two different parent types. - - var appendAllChildrenToContainer = function( - containerChildSet, - workInProgress, - needsVisibilityToggle, - isHidden - ) { - // We only have the top Fiber that was created but we need recurse down its - // children to find all the terminal nodes. - var node = workInProgress.child; - - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; - - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); - } - - appendChildToContainerChildSet(containerChildSet, instance); - } else if (node.tag === HostText) { - var _instance2 = node.stateNode; - - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance2 = cloneHiddenTextInstance(); - } - - appendChildToContainerChildSet(containerChildSet, _instance2); - } else if (node.tag === HostPortal); - else if (node.tag === OffscreenComponent && node.memoizedState !== null) { - // The children in this boundary are hidden. Toggle their visibility - // before appending. - var child = node.child; - - if (child !== null) { - child.return = node; - } - - { - appendAllChildrenToContainer(containerChildSet, node, true, true); - } - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } // $FlowFixMe This is correct but Flow is confused by the labeled break. - - node = node; - - if (node === workInProgress) { - return; - } - - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } - - node = node.return; - } - - node.sibling.return = node.return; - node = node.sibling; - } - }; - - updateHostContainer = function(current, workInProgress) { - var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); - - if (childrenUnchanged); - else { - var container = portalOrRoot.containerInfo; - var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set. - - appendAllChildrenToContainer(newChildSet, workInProgress, false, false); - portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. - - markUpdate(workInProgress); - finalizeContainerChildren(container, newChildSet); - } - }; - - updateHostComponent = function( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ) { - var currentInstance = current.stateNode; - var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates. - // This guarantees that we can reuse all of them. - - var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); - - if (childrenUnchanged && oldProps === newProps) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; - } - - var recyclableInstance = workInProgress.stateNode; - var currentHostContext = getHostContext(); - var updatePayload = null; - - if (oldProps !== newProps) { - updatePayload = prepareUpdate( - recyclableInstance, - type, - oldProps, - newProps - ); - } - - if (childrenUnchanged && updatePayload === null) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; - } - - var newInstance = cloneInstance( - currentInstance, - updatePayload, - type, - oldProps, - newProps, - workInProgress, - childrenUnchanged - ); - - workInProgress.stateNode = newInstance; - - if (childrenUnchanged) { - // If there are no other effects in this tree, we need to flag this node as having one. - // Even though we're not going to use it for anything. - // Otherwise parents won't know that there are new children to propagate upwards. - markUpdate(workInProgress); - } else { - // If children might have changed, we have to add them all to the set. - appendAllChildren(newInstance, workInProgress, false, false); - } - }; - - updateHostText = function(current, workInProgress, oldText, newText) { - if (oldText !== newText) { - // If the text content differs, we'll create a new text instance for it. - var rootContainerInstance = getRootHostContainer(); - var currentHostContext = getHostContext(); - workInProgress.stateNode = createTextInstance( - newText, - rootContainerInstance, - currentHostContext, - workInProgress - ); // We'll have to mark it as having an effect, even though we won't use the effect for anything. - // This lets the parents know that at least one of their children has changed. - - markUpdate(workInProgress); - } else { - workInProgress.stateNode = current.stateNode; - } - }; -} - -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": { - // Any insertions at the end of the tail list after this point - // should be invisible. If there are already mounted boundaries - // anything before them are not considered for collapsing. - // Therefore we need to go through the whole tail to find if - // there are any. - var tailNode = renderState.tail; - var lastTailNode = null; - - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; - } - - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. - - if (lastTailNode === null) { - // All remaining items in the tail are insertions. - renderState.tail = null; - } else { - // Detach the insertion after the last node that was already - // inserted. - lastTailNode.sibling = null; - } - - break; - } - - case "collapsed": { - // Any insertions at the end of the tail list after this point - // should be invisible. If there are already mounted boundaries - // anything before them are not considered for collapsing. - // Therefore we need to go through the whole tail to find if - // there are any. - var _tailNode = renderState.tail; - var _lastTailNode = null; - - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } - - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. - - if (_lastTailNode === null) { - // All remaining items in the tail are insertions. - if (!hasRenderedATailFallback && renderState.tail !== null) { - // We suspended during the head. We want to show at least one - // row at the tail. So we'll keep on and cut off the rest. - renderState.tail.sibling = null; - } else { - renderState.tail = null; - } - } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; - } - - break; - } - } -} - -function bubbleProperties(completedWork) { - var didBailout = - completedWork.alternate !== null && - completedWork.alternate.child === completedWork.child; - var newChildLanes = NoLanes; - var subtreeFlags = NoFlags; - - if (!didBailout) { - // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var actualDuration = completedWork.actualDuration; - var treeBaseDuration = completedWork.selfBaseDuration; - var child = completedWork.child; - - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) - ); - subtreeFlags |= child.subtreeFlags; - subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will - // only be updated if work is done on the fiber (i.e. it doesn't bailout). - // When work is done, it should bubble to the parent's actualDuration. If - // the fiber has not been cloned though, (meaning no work was done), then - // this value will reflect the amount of time spent working on a previous - // render. In that case it should not bubble. We determine whether it was - // cloned by comparing the child pointer. - - actualDuration += child.actualDuration; - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; - - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) - ); - subtreeFlags |= _child.subtreeFlags; - subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code - // smell because it assumes the commit phase is never concurrent with - // the render phase. Will address during refactor to alternate model. - - _child.return = completedWork; - _child = _child.sibling; - } - } - - completedWork.subtreeFlags |= subtreeFlags; - } else { - // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var _treeBaseDuration = completedWork.selfBaseDuration; - var _child2 = completedWork.child; - - while (_child2 !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child2.lanes, _child2.childLanes) - ); // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. - - subtreeFlags |= _child2.subtreeFlags & StaticMask; - subtreeFlags |= _child2.flags & StaticMask; - _treeBaseDuration += _child2.treeBaseDuration; - _child2 = _child2.sibling; - } - - completedWork.treeBaseDuration = _treeBaseDuration; - } else { - var _child3 = completedWork.child; - - while (_child3 !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child3.lanes, _child3.childLanes) - ); // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. - - subtreeFlags |= _child3.subtreeFlags & StaticMask; - subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code - // smell because it assumes the commit phase is never concurrent with - // the render phase. Will address during refactor to alternate model. - - _child3.return = completedWork; - _child3 = _child3.sibling; - } - } - - completedWork.subtreeFlags |= subtreeFlags; - } - - completedWork.childLanes = newChildLanes; - return didBailout; -} - -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing - // to the current tree provider fiber is just as fast and less error-prone. - // Ideally we would have a special version of the work loop only - // for hydration. - - popTreeContext(workInProgress); - - switch (workInProgress.tag) { - case IndeterminateComponent: - case LazyComponent: - case SimpleMemoComponent: - case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: - bubbleProperties(workInProgress); - return null; - - case ClassComponent: { - var Component = workInProgress.type; - - if (isContextProvider(Component)) { - popContext(workInProgress); - } - - bubbleProperties(workInProgress); - return null; - } - - case HostRoot: { - var fiberRoot = workInProgress.stateNode; - - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); - - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } - - if (current === null || current.child === null) { - // If we hydrated, pop so that we can delete any remaining children - // that weren't hydrated. - var wasHydrated = popHydrationState(); - - if (wasHydrated) { - // If we hydrated, then we'll need to schedule an update for - // the commit side-effects on the root. - markUpdate(workInProgress); - } else { - if (current !== null) { - var prevState = current.memoizedState; - - if ( - // Check if this is a client root - !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error) - (workInProgress.flags & ForceClientRender) !== NoFlags - ) { - // Schedule an effect to clear this container at the start of the - // next commit. This handles the case of React rendering into a - // container with previous children. It's also safe to do for - // updates too, because current.child would only be null if the - // previous render was null (so the container would already - // be empty). - workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been - } - } - } - } - - updateHostContainer(current, workInProgress); - bubbleProperties(workInProgress); - return null; - } - - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; - - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); - - if (current.ref !== workInProgress.ref) { - markRef(workInProgress); - } - } else { - if (!newProps) { - if (workInProgress.stateNode === null) { - throw new Error( - "We must have new props for new mounts. This error is likely " + - "caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. - - bubbleProperties(workInProgress); - return null; - } - - var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context - // "stack" as the parent. Then append children as we go in beginWork - // or completeWork depending on whether we want to add them top->down or - // bottom->up. Top->down is faster in IE11. - - var _wasHydrated = popHydrationState(); - - if (_wasHydrated) { - // TODO: Move this and createInstance step into the beginPhase - // to consolidate. - if (prepareToHydrateHostInstance()) { - // If changes to the hydrated node need to be applied at the - // commit-phase we mark this as such. - markUpdate(workInProgress); - } - } else { - var instance = createInstance( - type, - newProps, - rootContainerInstance, - currentHostContext, - workInProgress - ); - appendAllChildren(instance, workInProgress, false, false); - workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. - } - - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef(workInProgress); - } - } - - bubbleProperties(workInProgress); - return null; - } - - case HostText: { - var newText = newProps; - - if (current && workInProgress.stateNode != null) { - var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need - // to schedule a side-effect to do the updates. - - updateHostText(current, workInProgress, oldText, newText); - } else { - if (typeof newText !== "string") { - if (workInProgress.stateNode === null) { - throw new Error( - "We must have new props for new mounts. This error is likely " + - "caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. - } - - var _rootContainerInstance = getRootHostContainer(); - - var _currentHostContext = getHostContext(); - - var _wasHydrated2 = popHydrationState(); - - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } - - bubbleProperties(workInProgress); - return null; - } - - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; - - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. - - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } // Don't bubble properties in this case. - - return workInProgress; - } - - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; - - if (current === null); - else { - var _prevState = current.memoizedState; - prevDidTimeout = _prevState !== null; - } - // an effect to toggle the subtree's visibility. When we switch from - // fallback -> primary, the inner Offscreen fiber schedules this effect - // as part of its normal complete phase. But when we switch from - // primary -> fallback, the inner Offscreen fiber does not have a complete - // phase. So we need to schedule its effect here. - // - // We also use this flag to connect/disconnect the effects, but the same - // logic applies: when re-connecting, the Offscreen fiber's complete - // phase will handle scheduling the effect. It's only when the fallback - // is active that we have to do anything special. - - if (nextDidTimeout && !prevDidTimeout) { - var _offscreenFiber = workInProgress.child; - _offscreenFiber.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything - // in the concurrent tree already suspended during this render. - // This is a known bug. - - if ((workInProgress.mode & ConcurrentMode) !== NoMode) { - // TODO: Move this back to throwException because this is too late - // if this is a large tree which is common for initial loads. We - // don't know if we should restart a render or not until we get - // this marker, and this is too late. - // If this render already had a ping or lower pri updates, - // and this is the first time we know we're going to suspend we - // should be able to immediately restart from within throwException. - var hasInvisibleChildContext = - current === null && - (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || - !enableSuspenseAvoidThisFallback); - - if ( - hasInvisibleChildContext || - hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ) - ) { - // If this was in an invisible tree or a new render, then showing - // this boundary is ok. - renderDidSuspend(); - } else { - // Otherwise, we're going to have to hide content so we should - // suspend for longer if possible. - renderDidSuspendDelayIfPossible(); - } - } - } - - var wakeables = workInProgress.updateQueue; - - if (wakeables !== null) { - // Schedule an effect to attach a retry listener to the promise. - // TODO: Move to passive phase - workInProgress.flags |= Update; - } - - bubbleProperties(workInProgress); - - { - if ((workInProgress.mode & ProfileMode) !== NoMode) { - if (nextDidTimeout) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var _primaryChildFragment2 = workInProgress.child; - - if (_primaryChildFragment2 !== null) { - // $FlowFixMe Flow doesn't support type casting in combination with the -= operator - workInProgress.treeBaseDuration -= - _primaryChildFragment2.treeBaseDuration; - } - } - } - } - - return null; - } - - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(current, workInProgress); - - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } - - bubbleProperties(workInProgress); - return null; - - case ContextProvider: - // Pop provider fiber - var context = workInProgress.type._context; - popProvider(context, workInProgress); - bubbleProperties(workInProgress); - return null; - - case IncompleteClassComponent: { - // Same as class component case. I put it down here so that the tags are - // sequential to ensure this switch is compiled to a jump table. - var _Component = workInProgress.type; - - if (isContextProvider(_Component)) { - popContext(workInProgress); - } - - bubbleProperties(workInProgress); - return null; - } - - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; - - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - bubbleProperties(workInProgress); - return null; - } - - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; - - if (renderedTail === null) { - // We just rendered the head. - if (!didSuspendAlready) { - // This is the first pass. We need to figure out if anything is still - // suspended in the rendered set. - // If new content unsuspended, but there's still some content that - // didn't. Then we need to do a second pass that forces everything - // to keep showing their fallbacks. - // We might be suspended if something in this render pass suspended, or - // something in the previous committed pass suspended. Otherwise, - // there's no chance so we can skip the expensive call to - // findFirstSuspended. - var cannotBeSuspended = - renderHasNotSuspendedYet() && - (current === null || (current.flags & DidCapture) === NoFlags); - - if (!cannotBeSuspended) { - var row = workInProgress.child; - - while (row !== null) { - var suspended = findFirstSuspended(row); - - if (suspended !== null) { - didSuspendAlready = true; - workInProgress.flags |= DidCapture; - cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as - // part of the second pass. In that case nothing will subscribe to - // its thenables. Instead, we'll transfer its thenables to the - // SuspenseList so that it can retry if they resolve. - // There might be multiple of these in the list but since we're - // going to wait for all of them anyway, it doesn't really matter - // which ones gets to ping. In theory we could get clever and keep - // track of how many dependencies remain but it gets tricky because - // in the meantime, we can add/remove/change items and dependencies. - // We might bail out of the loop before finding any but that - // doesn't matter since that means that the other boundaries that - // we did find already has their listeners attached. - - var newThenables = suspended.updateQueue; - - if (newThenables !== null) { - workInProgress.updateQueue = newThenables; - workInProgress.flags |= Update; - } // Rerender the whole list, but this time, we'll force fallbacks - // to stay in place. - // Reset the effect flags before doing the second pass since that's now invalid. - // Reset the child fibers to their original state. - - workInProgress.subtreeFlags = NoFlags; - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. - - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); // Don't bubble properties in this case. - - return workInProgress.child; - } - - row = row.sibling; - } - } - - if (renderState.tail !== null && now() > getRenderTargetTime()) { - // We have already passed our CPU deadline but we still have rows - // left in the tail. We'll just give up further attempts to render - // the main content and only render fallbacks. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. - - workInProgress.lanes = SomeRetryLane; - } - } else { - cutOffTailIfNeeded(renderState, false); - } // Next we're going to render the tail. - } else { - // Append the rendered row to the child list. - if (!didSuspendAlready) { - var _suspended = findFirstSuspended(renderedTail); - - if (_suspended !== null) { - workInProgress.flags |= DidCapture; - didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't - // get lost if this row ends up dropped during a second pass. - - var _newThenables = _suspended.updateQueue; - - if (_newThenables !== null) { - workInProgress.updateQueue = _newThenables; - workInProgress.flags |= Update; - } - - cutOffTailIfNeeded(renderState, true); // This might have been modified. - - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate && - !getIsHydrating() // We don't cut it if we're hydrating. - ) { - // We're done. - bubbleProperties(workInProgress); - return null; - } - } else if ( - // The time it took to render last row is greater than the remaining - // time we have to render. So rendering one more row would likely - // exceed it. - now() * 2 - renderState.renderingStartTime > - getRenderTargetTime() && - renderLanes !== OffscreenLane - ) { - // We have now passed our CPU deadline and we'll just give up further - // attempts to render the main content and only render fallbacks. - // The assumption is that this is usually faster. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. - - workInProgress.lanes = SomeRetryLane; - } - } - - if (renderState.isBackwards) { - // The effect list of the backwards tail will have been added - // to the end. This breaks the guarantee that life-cycles fire in - // sibling order but that isn't a strong guarantee promised by React. - // Especially since these might also just pop in during future commits. - // Append to the beginning of the list. - renderedTail.sibling = workInProgress.child; - workInProgress.child = renderedTail; - } else { - var previousSibling = renderState.last; - - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } - - renderState.last = renderedTail; - } - } - - if (renderState.tail !== null) { - // We still have tail rows to render. - // Pop a row. - var next = renderState.tail; - renderState.rendering = next; - renderState.tail = next.sibling; - renderState.renderingStartTime = now(); - next.sibling = null; // Restore the context. - // TODO: We can probably just avoid popping it instead and only - // setting it the first time we go from not suspended to suspended. - - var suspenseContext = suspenseStackCursor.current; - - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } - - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - // Don't bubble properties in this case. - - return next; - } - - bubbleProperties(workInProgress); - return null; - } - - case ScopeComponent: { - break; - } - - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); - var _nextState = workInProgress.memoizedState; - var nextIsHidden = _nextState !== null; - - if (current !== null) { - var _prevState2 = current.memoizedState; - var prevIsHidden = _prevState2 !== null; - - if ( - prevIsHidden !== nextIsHidden && // LegacyHidden doesn't do any hiding — it only pre-renders. - !enableLegacyHidden - ) { - workInProgress.flags |= Visibility; - } - } - - if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) { - bubbleProperties(workInProgress); - } else { - // Don't bubble properties for hidden children unless we're rendering - // at offscreen priority. - if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { - bubbleProperties(workInProgress); - } - } - - return null; - } - - case CacheComponent: { - return null; - } - - case TracingMarkerComponent: { - return null; - } - } - - throw new Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in " + - "React. Please file an issue." - ); -} - var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; var didReceiveUpdate = false; var didWarnAboutBadClass; @@ -14697,7 +13853,23 @@ function updateSimpleMemoComponent( current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. workInProgress.type === current.type ) { - didReceiveUpdate = false; + didReceiveUpdate = false; // The props are shallowly equal. Reuse the previous props object, like we + // would during a normal fiber bailout. + // + // We don't have strong guarantees that the props object is referentially + // equal during updates where we can't bail out anyway — like if the props + // are shallowly equal, but there's a local state or context update in the + // same batch. + // + // However, as a principle, we should aim to make the behavior consistent + // across different ways of memoizing a component. For example, React.memo + // has a different internal Fiber layout if you pass a normal function + // component (SimpleMemoComponent) versus if you pass a different type + // like forwardRef (MemoComponent). But this is an implementation detail. + // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't + // affect whether the props object is reused during a bailout. + + workInProgress.pendingProps = nextProps = prevProps; if (!checkScheduledUpdateOrContext(current, renderLanes)) { // The pending lanes were cleared at the beginning of beginWork. We're @@ -14745,9 +13917,11 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { // Rendering a hidden tree. if ((workInProgress.mode & ConcurrentMode) === NoMode) { // In legacy sync mode, don't defer the subtree. Render it now. + // TODO: Consider how Offscreen should work with transitions in the future var nextState = { baseLanes: NoLanes, - cachePool: null + cachePool: null, + transitions: null }; workInProgress.memoizedState = nextState; @@ -14770,7 +13944,8 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { ); var _nextState = { baseLanes: nextBaseLanes, - cachePool: spawnedCachePool + cachePool: spawnedCachePool, + transitions: null }; workInProgress.memoizedState = _nextState; workInProgress.updateQueue = null; @@ -14785,7 +13960,8 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { // Rendering at offscreen, so we can clear the base lanes. var _nextState2 = { baseLanes: NoLanes, - cachePool: null + cachePool: null, + transitions: null }; workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. @@ -14813,11 +13989,9 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { pushRenderLanes(workInProgress, _subtreeRenderLanes); } - { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; - } -} + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} // Note: These happen to have identical begin phases, for now. We shouldn't hold function updateFragment(current, workInProgress, renderLanes) { var nextChildren = workInProgress.pendingProps; @@ -14850,7 +14024,7 @@ function updateProfiler(current, workInProgress, renderLanes) { return workInProgress.child; } -function markRef$1(current, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( @@ -14997,16 +14171,7 @@ function updateClassComponent( var shouldUpdate; if (instance === null) { - if (current !== null) { - // A class component without an instance only mounts if it suspended - // inside a non-concurrent tree, in an inconsistent state. We want to - // treat it like a new mount, even though an empty version of it already - // committed. Disconnect the alternate pointers. - current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } // In the initial pass we might need to construct the instance. + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance. constructClassInstance(workInProgress, Component, nextProps); mountClassInstance(workInProgress, Component, nextProps, renderLanes); @@ -15066,7 +14231,7 @@ function finishClassComponent( renderLanes ) { // Refs should update even if shouldComponentUpdate returns false - markRef$1(current, workInProgress); + markRef(current, workInProgress); var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; if (!shouldUpdate && !didCaptureError) { @@ -15179,7 +14344,7 @@ function updateHostRoot(current, workInProgress, renderLanes) { return workInProgress.child; } -function updateHostComponent$1(current, workInProgress, renderLanes) { +function updateHostComponent(current, workInProgress, renderLanes) { pushHostContext(workInProgress); var type = workInProgress.type; @@ -15193,12 +14358,12 @@ function updateHostComponent$1(current, workInProgress, renderLanes) { workInProgress.flags |= ContentReset; } - markRef$1(current, workInProgress); + markRef(current, workInProgress); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function updateHostText$1(current, workInProgress) { +function updateHostText(current, workInProgress) { // immediately after. return null; @@ -15210,17 +14375,7 @@ function mountLazyComponent( elementType, renderLanes ) { - if (_current !== null) { - // A lazy component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } - + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); var props = workInProgress.pendingProps; var lazyComponent = elementType; var payload = lazyComponent._payload; @@ -15341,16 +14496,7 @@ function mountIncompleteClassComponent( nextProps, renderLanes ) { - if (_current !== null) { - // An incomplete component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` // Push context providers early to prevent context stack mismatches. @@ -15385,17 +14531,7 @@ function mountIndeterminateComponent( Component, renderLanes ) { - if (_current !== null) { - // An indeterminate component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } - + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); var props = workInProgress.pendingProps; var context; @@ -15621,7 +14757,8 @@ var SUSPENDED_MARKER = { function mountSuspenseOffscreenState(renderLanes) { return { baseLanes: renderLanes, - cachePool: getSuspendedCache() + cachePool: getSuspendedCache(), + transitions: null }; } @@ -15630,7 +14767,8 @@ function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { return { baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), - cachePool: cachePool + cachePool: cachePool, + transitions: prevOffscreenState.transitions }; } // TODO: Probably should inline this back @@ -15722,6 +14860,16 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { // a stack. if (current === null) { + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null) { + var dehydrated = suspenseState.dehydrated; + + if (dehydrated !== null) { + return mountDehydratedSuspenseComponent(workInProgress); + } + } + var nextPrimaryChildren = nextProps.children; var nextFallbackChildren = nextProps.fallback; @@ -15737,98 +14885,67 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { renderLanes ); workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackFragment; } else { return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); } } else { // This is an update. - // If the current fiber has a SuspenseState, that means it's already showing - // a fallback. + // Special path for hydration var prevState = current.memoizedState; if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; + var _dehydrated = prevState.dehydrated; - var _fallbackChildFragment = updateSuspenseFallbackChildren( + if (_dehydrated !== null) { + return updateDehydratedSuspenseComponent( current, workInProgress, - _nextPrimaryChildren2, - _nextFallbackChildren2, + didSuspend, + nextProps, + _dehydrated, + prevState, renderLanes ); - - var _primaryChildFragment3 = workInProgress.child; - var prevOffscreenState = current.child.memoizedState; - _primaryChildFragment3.memoizedState = - prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); - _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment; - } else { - var _nextPrimaryChildren3 = nextProps.children; - - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren3, - renderLanes - ); - - workInProgress.memoizedState = null; - return _primaryChildFragment4; } + } + + if (showFallback) { + var _nextFallbackChildren = nextProps.fallback; + var _nextPrimaryChildren = nextProps.children; + var fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren, + _nextFallbackChildren, + renderLanes + ); + var _primaryChildFragment2 = workInProgress.child; + var prevOffscreenState = current.child.memoizedState; + _primaryChildFragment2.memoizedState = + prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); + + _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree( + current, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; } else { - // The current tree is not already showing a fallback. - if (showFallback) { - // Timed out. - var _nextFallbackChildren3 = nextProps.fallback; - var _nextPrimaryChildren4 = nextProps.children; + var _nextPrimaryChildren2 = nextProps.children; - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes - ); + var _primaryChildFragment3 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren2, + renderLanes + ); - var _primaryChildFragment5 = workInProgress.child; - var _prevOffscreenState = current.child.memoizedState; - _primaryChildFragment5.memoizedState = - _prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes); - _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes - ); // Skip the primary children, and continue working on the - // fallback children. - - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment2; - } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - var _nextPrimaryChildren5 = nextProps.children; - - var _primaryChildFragment6 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren5, - renderLanes - ); - - workInProgress.memoizedState = null; - return _primaryChildFragment6; - } + workInProgress.memoizedState = null; + return _primaryChildFragment3; } } } @@ -16008,7 +15125,7 @@ function updateSuspenseFallbackChildren( currentPrimaryChildFragment.selfBaseDuration; primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration; - } + } // The fallback fiber was added as a deletion during the first pass. // However, since we're going to remain on the fallback, we no longer want // to delete it. @@ -16017,7 +15134,7 @@ function updateSuspenseFallbackChildren( primaryChildFragment = updateWorkInProgressOffscreenFiber( currentPrimaryChildFragment, primaryChildProps - ); + ); // Since we're reusing a current tree, we need to reuse the flags, too. // (We don't do this in legacy mode, because in legacy mode we don't re-use // the current tree; see previous branch.) @@ -16051,6 +15168,288 @@ function updateSuspenseFallbackChildren( return fallbackChildFragment; } +function retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + recoverableError +) { + // Falling back to client rendering. Because this has performance + // implications, it's considered a recoverable error, even though the user + // likely won't observe anything wrong with the UI. + // + // The error is passed in as an argument to enforce that every caller provide + // a custom message, or explicitly opt out (currently the only path that opts + // out is legacy mode; every concurrent path provides an error). + if (recoverableError !== null) { + queueHydrationError(recoverableError); + } // This will add the old fiber to the deletion list + + reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated. + + var nextProps = workInProgress.pendingProps; + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren( + workInProgress, + primaryChildren + ); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. + + primaryChildFragment.flags |= Placement; + workInProgress.memoizedState = null; + return primaryChildFragment; +} + +function mountSuspenseFallbackAfterRetryWithoutHydrating( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var fiberMode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + fiberMode + ); + var fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + fiberMode, + renderLanes, + null + ); // Needs a placement effect because the parent (the Suspense + // boundary) already mounted but this is a new fiber. + + fallbackChildFragment.flags |= Placement; + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // We will have dropped the effect list which contains the + // deletion. We need to reconcile to delete the current child. + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + } + + return fallbackChildFragment; +} + +function mountDehydratedSuspenseComponent( + workInProgress, + suspenseInstance, + renderLanes +) { + // During the first pass, we'll bail out and not drill into the children. + // Instead, we'll leave the content in place and try to hydrate it later. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + { + error( + "Cannot hydrate Suspense in legacy mode. Switch from " + + "ReactDOM.hydrate(element, container) to " + + "ReactDOMClient.hydrateRoot(container, )" + + ".render(element) or remove the Suspense components from " + + "the server rendered components." + ); + } + + workInProgress.lanes = laneToLanes(SyncLane); + } else if (isSuspenseInstanceFallback()) { + // This is a client-only boundary. Since we won't get any content from the server + // for this, we need to schedule that at a higher priority based on when it would + // have timed out. In theory we could render it in this pass but it would have the + // wrong priority associated with it and will prevent hydration of parent path. + // Instead, we'll leave work left on it to render it in a separate commit. + // TODO This time should be the time at which the server rendered response that is + // a parent to this boundary was displayed. However, since we currently don't have + // a protocol to transfer that time, we'll just estimate it by using the current + // time. This will mean that Suspense timeouts are slightly shifted to later than + // they should be. + // Schedule a normal pri update to render this content. + workInProgress.lanes = laneToLanes(DefaultHydrationLane); + } else { + // We'll continue hydrating the rest at offscreen priority since we'll already + // be showing the right content coming from the server, it is no rush. + workInProgress.lanes = laneToLanes(OffscreenLane); + } + + return null; +} + +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + nextProps, + suspenseInstance, + suspenseState, + renderLanes +) { + if (!didSuspend) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, // TODO: When we delete legacy mode, we should make this error argument + // required — every concurrent mode path that causes hydration to + // de-opt to client rendering should have an error message. + null + ); + } + + if (isSuspenseInstanceFallback()) { + // This boundary is in a permanent fallback state. In this case, we'll never + // get an update and we'll never be able to hydrate the final content. Let's just try the + // client side render instead. + var _getSuspenseInstanceF = getSuspenseInstanceFallbackErrorDetails(), + errorMessage = _getSuspenseInstanceF.errorMessage; + + var error = errorMessage // eslint-disable-next-line react-internal/prod-error-codes + ? new Error(errorMessage) + : new Error( + "The server could not finish this Suspense boundary, likely " + + "due to an error during server rendering. Switched to " + + "client rendering." + ); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + error + ); + } + // any context has changed, we need to treat is as if the input might have changed. + + var hasContextChanged = includesSomeLane(renderLanes, current.childLanes); + + if (didReceiveUpdate || hasContextChanged) { + // This boundary has changed since the first render. This means that we are now unable to + // hydrate it. We might still be able to hydrate it using a higher priority lane. + var root = getWorkInProgressRoot(); + + if (root !== null) { + var attemptHydrationAtLane = getBumpedLaneForHydration( + root, + renderLanes + ); + + if ( + attemptHydrationAtLane !== NoLane && + attemptHydrationAtLane !== suspenseState.retryLane + ) { + // Intentionally mutating since this render will get interrupted. This + // is one of the very rare times where we mutate the current tree + // during the render phase. + suspenseState.retryLane = attemptHydrationAtLane; // TODO: Ideally this would inherit the event time of the current render + + var eventTime = NoTimestamp; + scheduleUpdateOnFiber(current, attemptHydrationAtLane, eventTime); + } + } // If we have scheduled higher pri work above, this will probably just abort the render + // since we now have higher priority work, but in case it doesn't, we need to prepare to + // render something, if we time out. Even if that requires us to delete everything and + // skip hydration. + // Delay having to do this as long as the suspense timeout allows us. + + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + new Error( + "This Suspense boundary received an update before it finished " + + "hydrating. This caused the boundary to switch to client rendering. " + + "The usual way to fix this is to wrap the original update " + + "in startTransition." + ) + ); + } else if (isSuspenseInstancePending()) { + // This component is still pending more data from the server, so we can't hydrate its + // content. We treat it as if this component suspended itself. It might seem as if + // we could just try to render it client-side instead. However, this will perform a + // lot of unnecessary work and is unlikely to complete since it often will suspend + // on missing data anyway. Additionally, the server might be able to render more + // than we can on the client yet. In that case we'd end up with more fallback states + // on the client than if we just leave it alone. If the server times out or errors + // these should update this boundary to the permanent Fallback state instead. + // Mark it as having captured (i.e. suspended). + workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. + + workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result. + + var retry = retryDehydratedSuspenseBoundary.bind(null, current); + registerSuspenseInstanceRetry(); + return null; + } else { + // This is the first attempt. + reenterHydrationStateFromDehydratedSuspenseInstance( + workInProgress, + suspenseInstance, + suspenseState.treeContext + ); + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren( + workInProgress, + primaryChildren + ); // Mark the children as hydrating. This is a fast path to know whether this + // tree is part of a hydrating tree. This is used to determine if a child + // node has fully mounted yet, and for scheduling event replaying. + // Conceptually this is similar to Placement in that a new subtree is + // inserted into the React tree here. It just happens to not need DOM + // mutations because it already exists. + + primaryChildFragment.flags |= Hydrating; + return primaryChildFragment; + } + } else { + // This is the second render pass. We already attempted to hydrated, but + // something either suspended or errored. + if (workInProgress.flags & ForceClientRender) { + // Something errored during hydration. Try again without hydrating. + workInProgress.flags &= ~ForceClientRender; + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + new Error( + "There was an error while hydrating this Suspense boundary. " + + "Switched to client rendering." + ) + ); + } else if (workInProgress.memoizedState !== null) { + // Something suspended and we should still be in dehydrated mode. + // Leave the existing child in place. + workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there + // but the normal suspense pass doesn't. + + workInProgress.flags |= DidCapture; + return null; + } else { + // Suspended but we should no longer be in dehydrated mode. + // Therefore we now have to render the fallback. + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating( + current, + workInProgress, + nextPrimaryChildren, + nextFallbackChildren, + renderLanes + ); + var _primaryChildFragment4 = workInProgress.child; + _primaryChildFragment4.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; + } + } +} + function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes = mergeLanes(fiber.lanes, renderLanes); var alternate = fiber.alternate; @@ -16596,6 +15995,21 @@ function markWorkInProgressReceivedUpdate() { didReceiveUpdate = true; } +function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if (current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + + workInProgress.flags |= Placement; + } + } +} + function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { if (current !== null) { // Reuse previous dependencies @@ -16757,6 +16171,19 @@ function attemptEarlyBailoutIfNoScheduledUpdate( var state = workInProgress.memoizedState; if (state !== null) { + if (state.dehydrated !== null) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has + // been unsuspended it has committed as a resolved Suspense component. + // If it needs to be retried, it should have work scheduled on it. + + workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we + // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork. + + return null; + } // If this boundary is currently timed out, we need to decide // whether to retry the primary children, or to skip over it and // go straight to the fallback. Check the priority of the primary // child fragment. @@ -17006,10 +16433,10 @@ function beginWork(current, workInProgress, renderLanes) { return updateHostRoot(current, workInProgress, renderLanes); case HostComponent: - return updateHostComponent$1(current, workInProgress, renderLanes); + return updateHostComponent(current, workInProgress, renderLanes); case HostText: - return updateHostText$1(); + return updateHostText(); case SuspenseComponent: return updateSuspenseComponent(current, workInProgress, renderLanes); @@ -17130,6 +16557,1160 @@ function beginWork(current, workInProgress, renderLanes) { ); } +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; +} + +function markRef$1(workInProgress) { + workInProgress.flags |= Ref; +} + +function hadNoMutationsEffects(current, completedWork) { + var didBailout = current !== null && current.child === completedWork.child; + + if (didBailout) { + return true; + } + + if ((completedWork.flags & ChildDeletion) !== NoFlags) { + return false; + } // TODO: If we move the `hadNoMutationsEffects` call after `bubbleProperties` + // then we only have to check the `completedWork.subtreeFlags`. + + var child = completedWork.child; + + while (child !== null) { + if ( + (child.flags & MutationMask) !== NoFlags || + (child.subtreeFlags & MutationMask) !== NoFlags + ) { + return false; + } + + child = child.sibling; + } + + return true; +} + +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; + +{ + // Persistent host tree mode + appendAllChildren = function( + parent, + workInProgress, + needsVisibilityToggle, + isHidden + ) { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; + + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); + } + + appendInitialChild(parent, instance); + } else if (node.tag === HostText) { + var _instance = node.stateNode; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance = cloneHiddenTextInstance(); + } + + appendInitialChild(parent, _instance); + } else if (node.tag === HostPortal); + else if (node.tag === OffscreenComponent && node.memoizedState !== null) { + // The children in this boundary are hidden. Toggle their visibility + // before appending. + var child = node.child; + + if (child !== null) { + child.return = node; + } + + appendAllChildren(parent, node, true, true); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } // $FlowFixMe This is correct but Flow is confused by the labeled break. + + node = node; + + if (node === workInProgress) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + }; // An unfortunate fork of appendAllChildren because we have two different parent types. + + var appendAllChildrenToContainer = function( + containerChildSet, + workInProgress, + needsVisibilityToggle, + isHidden + ) { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; + + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); + } + + appendChildToContainerChildSet(containerChildSet, instance); + } else if (node.tag === HostText) { + var _instance2 = node.stateNode; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance2 = cloneHiddenTextInstance(); + } + + appendChildToContainerChildSet(containerChildSet, _instance2); + } else if (node.tag === HostPortal); + else if (node.tag === OffscreenComponent && node.memoizedState !== null) { + // The children in this boundary are hidden. Toggle their visibility + // before appending. + var child = node.child; + + if (child !== null) { + child.return = node; + } + + appendAllChildrenToContainer(containerChildSet, node, true, true); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } // $FlowFixMe This is correct but Flow is confused by the labeled break. + + node = node; + + if (node === workInProgress) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + }; + + updateHostContainer = function(current, workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); + + if (childrenUnchanged); + else { + var container = portalOrRoot.containerInfo; + var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set. + + appendAllChildrenToContainer(newChildSet, workInProgress, false, false); + portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + + markUpdate(workInProgress); + finalizeContainerChildren(container, newChildSet); + } + }; + + updateHostComponent$1 = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + var currentInstance = current.stateNode; + var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates. + // This guarantees that we can reuse all of them. + + var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); + + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } + + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = null; + + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, + type, + oldProps, + newProps + ); + } + + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } + + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged + ); + + workInProgress.stateNode = newInstance; + + if (childrenUnchanged) { + // If there are no other effects in this tree, we need to flag this node as having one. + // Even though we're not going to use it for anything. + // Otherwise parents won't know that there are new children to propagate upwards. + markUpdate(workInProgress); + } else { + // If children might have changed, we have to add them all to the set. + appendAllChildren(newInstance, workInProgress, false, false); + } + }; + + updateHostText$1 = function(current, workInProgress, oldText, newText) { + if (oldText !== newText) { + // If the text content differs, we'll create a new text instance for it. + var rootContainerInstance = getRootHostContainer(); + var currentHostContext = getHostContext(); + workInProgress.stateNode = createTextInstance( + newText, + rootContainerInstance, + currentHostContext, + workInProgress + ); // We'll have to mark it as having an effect, even though we won't use the effect for anything. + // This lets the parents know that at least one of their children has changed. + + markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; + } + }; +} + +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; + + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } + + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + } + + break; + } + + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; + + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } + + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + } + + break; + } + } +} + +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; + + if (!didBailout) { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var actualDuration = completedWork.actualDuration; + var treeBaseDuration = completedWork.selfBaseDuration; + var child = completedWork.child; + + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes) + ); + subtreeFlags |= child.subtreeFlags; + subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will + // only be updated if work is done on the fiber (i.e. it doesn't bailout). + // When work is done, it should bubble to the parent's actualDuration. If + // the fiber has not been cloned though, (meaning no work was done), then + // this value will reflect the amount of time spent working on a previous + // render. In that case it should not bubble. We determine whether it was + // cloned by comparing the child pointer. + + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } + + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; + + while (_child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child.lanes, _child.childLanes) + ); + subtreeFlags |= _child.subtreeFlags; + subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child.return = completedWork; + _child = _child.sibling; + } + } + + completedWork.subtreeFlags |= subtreeFlags; + } else { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var _treeBaseDuration = completedWork.selfBaseDuration; + var _child2 = completedWork.child; + + while (_child2 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child2.lanes, _child2.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + + subtreeFlags |= _child2.subtreeFlags & StaticMask; + subtreeFlags |= _child2.flags & StaticMask; + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } + + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; + + while (_child3 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child3.lanes, _child3.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + + subtreeFlags |= _child3.subtreeFlags & StaticMask; + subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } + + completedWork.subtreeFlags |= subtreeFlags; + } + + completedWork.childLanes = newChildLanes; + return didBailout; +} + +function completeDehydratedSuspenseBoundary( + current, + workInProgress, + nextState +) { + var wasHydrated = popHydrationState(); + + if (nextState !== null && nextState.dehydrated !== null) { + // We might be inside a hydration state the first time we're picking up this + // Suspense boundary, and also after we've reentered it for further hydration. + if (current === null) { + if (!wasHydrated) { + throw new Error( + "A dehydrated suspense component was completed without a hydrated node. " + + "This is probably a bug in React." + ); + } + + prepareToHydrateHostSuspenseInstance(); + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var isTimedOutSuspense = nextState !== null; + + if (isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + + if (primaryChildFragment !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + primaryChildFragment.treeBaseDuration; + } + } + } + } + + return false; + } else { + if ((workInProgress.flags & DidCapture) === NoFlags) { + // This boundary did not suspend so it's now hydrated and unsuspended. + workInProgress.memoizedState = null; + } // If nothing suspended, we need to schedule an effect to mark this boundary + // as having hydrated so events know that they're free to be invoked. + // It's also a signal to replay events and the suspense callback. + // If something suspended, schedule an effect to attach retry listeners. + // So we might as well always mark this. + + workInProgress.flags |= Update; + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var _isTimedOutSuspense = nextState !== null; + + if (_isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var _primaryChildFragment = workInProgress.child; + + if (_primaryChildFragment !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment.treeBaseDuration; + } + } + } + } + + return false; + } + } else { + // Successfully completed this tree. If this was a forced client render, + // there may have been recoverable errors during first hydration + // attempt. If so, add them to a queue so we can log them in the + // commit phase. + upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path + + return true; + } +} + +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing + // to the current tree provider fiber is just as fast and less error-prone. + // Ideally we would have a special version of the work loop only + // for hydration. + + popTreeContext(workInProgress); + + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); + return null; + + case ClassComponent: { + var Component = workInProgress.type; + + if (isContextProvider(Component)) { + popContext(workInProgress); + } + + bubbleProperties(workInProgress); + return null; + } + + case HostRoot: { + var fiberRoot = workInProgress.stateNode; + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); + + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } + + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(); + + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + } else { + if (current !== null) { + var prevState = current.memoizedState; + + if ( + // Check if this is a client root + !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error) + (workInProgress.flags & ForceClientRender) !== NoFlags + ) { + // Schedule an effect to clear this container at the start of the + // next commit. This handles the case of React rendering into a + // container with previous children. It's also safe to do for + // updates too, because current.child would only be null if the + // previous render was null (so the container would already + // be empty). + workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been + // recoverable errors during first hydration attempt. If so, add + // them to a queue so we can log them in the commit phase. + + upgradeHydrationErrorsToRecoverable(); + } + } + } + } + + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + + return null; + } + + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); + + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } + } else { + if (!newProps) { + if (workInProgress.stateNode === null) { + throw new Error( + "We must have new props for new mounts. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + + bubbleProperties(workInProgress); + return null; + } + + var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context + // "stack" as the parent. Then append children as we go in beginWork + // or completeWork depending on whether we want to add them top->down or + // bottom->up. Top->down is faster in IE11. + + var _wasHydrated = popHydrationState(); + + if (_wasHydrated) { + // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + if (prepareToHydrateHostInstance()) { + // If changes to the hydrated node need to be applied at the + // commit-phase we mark this as such. + markUpdate(workInProgress); + } + } else { + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress + ); + appendAllChildren(instance, workInProgress, false, false); + workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. + } + + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + } + + bubbleProperties(workInProgress); + return null; + } + + case HostText: { + var newText = newProps; + + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. + + updateHostText$1(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (workInProgress.stateNode === null) { + throw new Error( + "We must have new props for new mounts. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + } + + var _rootContainerInstance = getRootHostContainer(); + + var _currentHostContext = getHostContext(); + + var _wasHydrated2 = popHydrationState(); + + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } + } + + bubbleProperties(workInProgress); + return null; + } + + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this + // to its own fiber type so that we can add other kinds of hydration + // boundaries that aren't associated with a Suspense tree. In anticipation + // of such a refactor, all the hydration logic is contained in + // this branch. + + if ( + current === null || + (current.memoizedState !== null && + current.memoizedState.dehydrated !== null) + ) { + var fallthroughToNormalSuspensePath = completeDehydratedSuspenseBoundary( + current, + workInProgress, + nextState + ); + + if (!fallthroughToNormalSuspensePath) { + if (workInProgress.flags & ShouldCapture) { + // Special case. There were remaining unhydrated nodes. We treat + // this as a mismatch. Revert to client rendering. + return workInProgress; + } else { + // Did not finish hydrating, either because this is the initial + // render or because something suspended. + return null; + } + } // Continue with the normal Suspense path. + } + + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. + + return workInProgress; + } + + var nextDidTimeout = nextState !== null; + var prevDidTimeout = current !== null && current.memoizedState !== null; + // a passive effect, which is when we process the transitions + + if (nextDidTimeout !== prevDidTimeout) { + // an effect to toggle the subtree's visibility. When we switch from + // fallback -> primary, the inner Offscreen fiber schedules this effect + // as part of its normal complete phase. But when we switch from + // primary -> fallback, the inner Offscreen fiber does not have a complete + // phase. So we need to schedule its effect here. + // + // We also use this flag to connect/disconnect the effects, but the same + // logic applies: when re-connecting, the Offscreen fiber's complete + // phase will handle scheduling the effect. It's only when the fallback + // is active that we have to do anything special. + + if (nextDidTimeout) { + var _offscreenFiber2 = workInProgress.child; + _offscreenFiber2.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything + // in the concurrent tree already suspended during this render. + // This is a known bug. + + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // TODO: Move this back to throwException because this is too late + // if this is a large tree which is common for initial loads. We + // don't know if we should restart a render or not until we get + // this marker, and this is too late. + // If this render already had a ping or lower pri updates, + // and this is the first time we know we're going to suspend we + // should be able to immediately restart from within throwException. + var hasInvisibleChildContext = + current === null && + (workInProgress.memoizedProps.unstable_avoidThisFallback !== + true || + !enableSuspenseAvoidThisFallback); + + if ( + hasInvisibleChildContext || + hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ) + ) { + // If this was in an invisible tree or a new render, then showing + // this boundary is ok. + renderDidSuspend(); + } else { + // Otherwise, we're going to have to hide content so we should + // suspend for longer if possible. + renderDidSuspendDelayIfPossible(); + } + } + } + } + + var wakeables = workInProgress.updateQueue; + + if (wakeables !== null) { + // Schedule an effect to attach a retry listener to the promise. + // TODO: Move to passive phase + workInProgress.flags |= Update; + } + + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + + if (primaryChildFragment !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + primaryChildFragment.treeBaseDuration; + } + } + } + } + + return null; + } + + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); + + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); + } + + bubbleProperties(workInProgress); + return null; + + case ContextProvider: + // Pop provider fiber + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; + + case IncompleteClassComponent: { + // Same as class component case. I put it down here so that the tags are + // sequential to ensure this switch is compiled to a jump table. + var _Component = workInProgress.type; + + if (isContextProvider(_Component)) { + popContext(workInProgress); + } + + bubbleProperties(workInProgress); + return null; + } + + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } + + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; + + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || (current.flags & DidCapture) === NoFlags); + + if (!cannotBeSuspended) { + var row = workInProgress.child; + + while (row !== null) { + var suspended = findFirstSuspended(row); + + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.flags |= DidCapture; + cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as + // part of the second pass. In that case nothing will subscribe to + // its thenables. Instead, we'll transfer its thenables to the + // SuspenseList so that it can retry if they resolve. + // There might be multiple of these in the list but since we're + // going to wait for all of them anyway, it doesn't really matter + // which ones gets to ping. In theory we could get clever and keep + // track of how many dependencies remain but it gets tricky because + // in the meantime, we can add/remove/change items and dependencies. + // We might bail out of the loop before finding any but that + // doesn't matter since that means that the other boundaries that + // we did find already has their listeners attached. + + var newThenables = suspended.updateQueue; + + if (newThenables !== null) { + workInProgress.updateQueue = newThenables; + workInProgress.flags |= Update; + } // Rerender the whole list, but this time, we'll force fallbacks + // to stay in place. + // Reset the effect flags before doing the second pass since that's now invalid. + // Reset the child fibers to their original state. + + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. + + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. + + return workInProgress.child; + } + + row = row.sibling; + } + } + + if (renderState.tail !== null && now() > getRenderTargetTime()) { + // We have already passed our CPU deadline but we still have rows + // left in the tail. We'll just give up further attempts to render + // the main content and only render fallbacks. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + + workInProgress.lanes = SomeRetryLane; + } + } else { + cutOffTailIfNeeded(renderState, false); + } // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); + + if (_suspended !== null) { + workInProgress.flags |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. + + var _newThenables = _suspended.updateQueue; + + if (_newThenables !== null) { + workInProgress.updateQueue = _newThenables; + workInProgress.flags |= Update; + } + + cutOffTailIfNeeded(renderState, true); // This might have been modified. + + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate && + !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We're done. + bubbleProperties(workInProgress); + return null; + } + } else if ( + // The time it took to render last row is greater than the remaining + // time we have to render. So rendering one more row would likely + // exceed it. + now() * 2 - renderState.renderingStartTime > + getRenderTargetTime() && + renderLanes !== OffscreenLane + ) { + // We have now passed our CPU deadline and we'll just give up further + // attempts to render the main content and only render fallbacks. + // The assumption is that this is usually faster. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + + workInProgress.lanes = SomeRetryLane; + } + } + + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; + + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } + + renderState.last = renderedTail; + } + } + + if (renderState.tail !== null) { + // We still have tail rows to render. + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.renderingStartTime = now(); + next.sibling = null; // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + + var suspenseContext = suspenseStackCursor.current; + + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } + + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. + + return next; + } + + bubbleProperties(workInProgress); + return null; + } + + case ScopeComponent: { + break; + } + + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; + + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; + + if ( + prevIsHidden !== nextIsHidden && // LegacyHidden doesn't do any hiding — it only pre-renders. + !enableLegacyHidden + ) { + workInProgress.flags |= Visibility; + } + } + + if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) { + bubbleProperties(workInProgress); + } else { + // Don't bubble properties for hidden children unless we're rendering + // at offscreen priority. + if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { + bubbleProperties(workInProgress); + } + } + return null; + } + + case CacheComponent: { + return null; + } + + case TracingMarkerComponent: { + return null; + } + } + + throw new Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in " + + "React. Please file an issue." + ); +} + function unwindWork(current, workInProgress, renderLanes) { // Note: This intentionally doesn't check if we're hydrating because comparing // to the current tree provider fiber is just as fast and less error-prone. @@ -17161,6 +17742,7 @@ function unwindWork(current, workInProgress, renderLanes) { } case HostRoot: { + var root = workInProgress.stateNode; popHostContainer(workInProgress); popTopLevelContextObject(workInProgress); resetWorkInProgressVersions(); @@ -17187,6 +17769,16 @@ function unwindWork(current, workInProgress, renderLanes) { case SuspenseComponent: { popSuspenseContext(workInProgress); + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null && suspenseState.dehydrated !== null) { + if (workInProgress.alternate === null) { + throw new Error( + "Threw in newly mounted dehydrated component. This is likely a bug in " + + "React. Please file an issue." + ); + } + } var _flags2 = workInProgress.flags; @@ -17222,7 +17814,6 @@ function unwindWork(current, workInProgress, renderLanes) { case OffscreenComponent: case LegacyHiddenComponent: popRenderLanes(workInProgress); - return null; case CacheComponent: @@ -17252,6 +17843,7 @@ function unwindInterruptedWork(current, interruptedWork, renderLanes) { } case HostRoot: { + var root = interruptedWork.stateNode; popHostContainer(interruptedWork); popTopLevelContextObject(interruptedWork); resetWorkInProgressVersions(); @@ -17283,7 +17875,6 @@ function unwindInterruptedWork(current, interruptedWork, renderLanes) { case OffscreenComponent: case LegacyHiddenComponent: popRenderLanes(interruptedWork); - break; } } @@ -17298,7 +17889,6 @@ var nextEffect = null; // Used for Profiling builds to track updaters. var inProgressLanes = null; var inProgressRoot = null; - function reportUncaughtErrorInDEV(error) { // Wrapping each small part of the commit phase into a guarded // callback is a bit too slow (https://github.com/facebook/react/pull/21666). @@ -17337,7 +17927,6 @@ function safelyCallComponentWillUnmount( try { callComponentWillUnmountWithTimer(current, instance); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(current, nearestMountedAncestor, error); } } // Capture errors so they don't interrupt mounting. @@ -17365,7 +17954,6 @@ function safelyDetachRef(current, nearestMountedAncestor) { retVal = ref(null); } } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(current, nearestMountedAncestor, error); } @@ -17388,7 +17976,6 @@ function safelyCallDestroy(current, nearestMountedAncestor, destroy) { try { destroy(); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(current, nearestMountedAncestor, error); } } @@ -17416,7 +18003,7 @@ function commitBeforeMutationEffects_begin() { (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null ) { - ensureCorrectReturnPointer(child, fiber); + child.return = fiber; nextEffect = child; } else { commitBeforeMutationEffects_complete(); @@ -17432,7 +18019,6 @@ function commitBeforeMutationEffects_complete() { try { commitBeforeMutationEffectsOnFiber(fiber); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(fiber, fiber.return, error); } @@ -17440,7 +18026,7 @@ function commitBeforeMutationEffects_complete() { var sibling = fiber.sibling; if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); + sibling.return = fiber.return; nextEffect = sibling; return; } @@ -17569,7 +18155,19 @@ function commitHookEffectListUnmount( effect.destroy = undefined; if (destroy !== undefined) { + { + if ((flags & Insertion) !== NoFlags$1) { + setIsRunningInsertionEffect(true); + } + } + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + + { + if ((flags & Insertion) !== NoFlags$1) { + setIsRunningInsertionEffect(false); + } + } } } @@ -17589,8 +18187,21 @@ function commitHookEffectListMount(flags, finishedWork) { do { if ((effect.tag & flags) === flags) { var create = effect.create; + + { + if ((flags & Insertion) !== NoFlags$1) { + setIsRunningInsertionEffect(true); + } + } + effect.destroy = create(); + { + if ((flags & Insertion) !== NoFlags$1) { + setIsRunningInsertionEffect(false); + } + } + { var destroy = effect.destroy; @@ -18005,7 +18616,8 @@ function commitLayoutEffectOnFiber( case IncompleteClassComponent: case ScopeComponent: case OffscreenComponent: - case LegacyHiddenComponent: { + case LegacyHiddenComponent: + case TracingMarkerComponent: { break; } @@ -18081,153 +18693,6 @@ function commitAttachRef(finishedWork) { } } -function commitDetachRef(current) { - var currentRef = current.ref; - - if (currentRef !== null) { - if (typeof currentRef === "function") { - if (current.mode & ProfileMode) { - try { - startLayoutEffectTimer(); - currentRef(null); - } finally { - recordLayoutEffectDuration(current); - } - } else { - currentRef(null); - } - } else { - currentRef.current = null; - } - } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay - -function commitUnmount(finishedRoot, current, nearestMountedAncestor) { - onCommitUnmount(current); - - switch (current.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - var updateQueue = current.updateQueue; - - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; - - do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; - - if (destroy !== undefined) { - if ((tag & Insertion) !== NoFlags$1) { - safelyCallDestroy(current, nearestMountedAncestor, destroy); - } else if ((tag & Layout) !== NoFlags$1) { - if (current.mode & ProfileMode) { - startLayoutEffectTimer(); - safelyCallDestroy(current, nearestMountedAncestor, destroy); - recordLayoutEffectDuration(current); - } else { - safelyCallDestroy(current, nearestMountedAncestor, destroy); - } - } - } - - effect = effect.next; - } while (effect !== firstEffect); - } - } - - return; - } - - case ClassComponent: { - safelyDetachRef(current, nearestMountedAncestor); - var instance = current.stateNode; - - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount( - current, - nearestMountedAncestor, - instance - ); - } - - return; - } - - case HostComponent: { - safelyDetachRef(current, nearestMountedAncestor); - return; - } - - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - emptyPortalContainer(current); - } - - return; - } - - case DehydratedFragment: { - return; - } - - case ScopeComponent: { - return; - } - } -} - -function commitNestedUnmounts(finishedRoot, root, nearestMountedAncestor) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; - - while (true) { - commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. - - if ( - node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. - // If we don't use mutation we drill down into portals here instead. - !supportsMutation - ) { - node.child.return = node; - node = node.child; - continue; - } - - if (node === root) { - return; - } - - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } - - node = node.return; - } - - node.sibling.return = node.return; - node = node.sibling; - } -} - function detachFiberMutation(fiber) { // Cut off the return pointer to disconnect it from the tree. // This enables us to detect and warn against state updates on an unmounted component. @@ -18317,110 +18782,194 @@ function emptyPortalContainer(current) { var emptyChildSet = createContainerChildSet(containerInfo); } -function commitContainer(finishedWork) { - switch (finishedWork.tag) { - case ClassComponent: - case HostComponent: - case HostText: { - return; - } - - case HostRoot: - case HostPortal: { - var portalOrRoot = finishedWork.stateNode; - var containerInfo = portalOrRoot.containerInfo, - pendingChildren = portalOrRoot.pendingChildren; - return; - } - } - - throw new Error( - "This unit of work tag should not have side-effects. This error is " + - "likely caused by a bug in React. Please file an issue." - ); +function commitPlacement(finishedWork) { + { + return; + } // Recursively insert all host nodes into the parent. } -function commitDeletion(finishedRoot, current, nearestMountedAncestor) { +function commitDeletionEffects(root, returnFiber, deletedFiber) { { // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts(finishedRoot, current, nearestMountedAncestor); + commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber); } - detachFiberMutation(current); + detachFiberMutation(deletedFiber); } -function commitWork(current, finishedWork) { - { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - commitHookEffectListUnmount( - Insertion | HasEffect, - finishedWork, - finishedWork.return +function recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + parent +) { + // TODO: Use a static flag to skip trees that don't have unmount effects + var child = parent.child; + + while (child !== null) { + commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child); + child = child.sibling; + } +} + +function commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + deletedFiber +) { + onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse + // into their subtree. There are simpler cases in the inner switch + // that don't modify the stack. + + switch (deletedFiber.tag) { + case HostComponent: { + { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + } // Intentional fallthrough to next branch + } + // eslint-disable-next-line-no-fallthrough + + case HostText: { + // We only need to remove the nearest host child. Set the host parent + // to `null` on the stack to indicate that nested children don't + // need to be removed. + { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber ); - commitHookEffectListMount(Insertion | HasEffect, finishedWork); // Layout effects are destroyed during the mutation phase so that all - // destroy functions for all fibers are called before any create functions. - // This prevents sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. - // TODO: Check if we're inside an Offscreen subtree that disappeared - // during this commit. If so, we would have already unmounted its - // layout hooks. (However, since we null out the `destroy` function - // right before calling it, the behavior is already correct, so this - // would mostly be for modeling purposes.) - - if (finishedWork.mode & ProfileMode) { - try { - startLayoutEffectTimer(); - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); - } finally { - recordLayoutEffectDuration(finishedWork); - } - } else { - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); - } - - return; } - case Profiler: { - return; - } - - case SuspenseComponent: { - commitSuspenseCallback(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; - } - - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } - - case HostRoot: { - break; - } - - case OffscreenComponent: - case LegacyHiddenComponent: { - return; - } + return; } - commitContainer(finishedWork); - return; + case DehydratedFragment: { + return; + } + + case HostPortal: { + { + emptyPortalContainer(deletedFiber); + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + } + + return; + } + + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + { + var updateQueue = deletedFiber.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + + if (destroy !== undefined) { + if ((tag & Insertion) !== NoFlags$1) { + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + } else if ((tag & Layout) !== NoFlags$1) { + if (deletedFiber.mode & ProfileMode) { + startLayoutEffectTimer(); + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + recordLayoutEffectDuration(deletedFiber); + } else { + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } + } + + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case ClassComponent: { + { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + var instance = deletedFiber.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + deletedFiber, + nearestMountedAncestor, + instance + ); + } + } + + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case ScopeComponent: { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case OffscreenComponent: { + { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + } + + break; + } + + default: { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } } } @@ -18468,158 +19017,275 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } // This function detects when a Suspense boundary goes from visible to hidden. - -function commitMutationEffects(root, firstChild, committedLanes) { +function commitMutationEffects(root, finishedWork, committedLanes) { inProgressLanes = committedLanes; inProgressRoot = root; - nextEffect = firstChild; - commitMutationEffects_begin(root, committedLanes); + setCurrentFiber(finishedWork); + commitMutationEffectsOnFiber(finishedWork, root); + setCurrentFiber(finishedWork); inProgressLanes = null; inProgressRoot = null; } -function commitMutationEffects_begin(root, lanes) { - while (nextEffect !== null) { - var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization +function recursivelyTraverseMutationEffects(root, parentFiber, lanes) { + // Deletions effects can be scheduled on any fiber type. They need to happen + // before the children effects hae fired. + var deletions = parentFiber.deletions; - var deletions = fiber.deletions; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; - if (deletions !== null) { - for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; - - try { - commitDeletion(root, childToDelete, fiber); - } catch (error) { - reportUncaughtErrorInDEV(error); - captureCommitPhaseError(childToDelete, fiber, error); - } + try { + commitDeletionEffects(root, parentFiber, childToDelete); + } catch (error) { + captureCommitPhaseError(childToDelete, parentFiber, error); } } + } - var child = fiber.child; + var prevDebugFiber = getCurrentFiber(); - if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitMutationEffects_complete(root, lanes); + if (parentFiber.subtreeFlags & MutationMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + commitMutationEffectsOnFiber(child, root); + child = child.sibling; } } -} -function commitMutationEffects_complete(root, lanes) { - while (nextEffect !== null) { - var fiber = nextEffect; - setCurrentFiber(fiber); - - try { - commitMutationEffectsOnFiber(fiber, root, lanes); - } catch (error) { - reportUncaughtErrorInDEV(error); - captureCommitPhaseError(fiber, fiber.return, error); - } - - resetCurrentFiber(); - var sibling = fiber.sibling; - - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; - return; - } - - nextEffect = fiber.return; - } + setCurrentFiber(prevDebugFiber); } function commitMutationEffectsOnFiber(finishedWork, root, lanes) { - // TODO: The factoring of this phase could probably be improved. Consider - // switching on the type of work before checking the flags. That's what - // we do in all the other phases. I think this one is only different - // because of the shared reconciliation logic below. - var flags = finishedWork.flags; + var current = finishedWork.alternate; + var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber, + // because the fiber tag is more specific. An exception is any flag related + // to reconcilation, because those can be set on all fiber types. - if (flags & Ref) { - var current = finishedWork.alternate; + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); - if (current !== null) { - commitDetachRef(current); + if (flags & Update) { + try { + commitHookEffectListUnmount( + Insertion | HasEffect, + finishedWork, + finishedWork.return + ); + commitHookEffectListMount(Insertion | HasEffect, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + + if (finishedWork.mode & ProfileMode) { + try { + startLayoutEffectTimer(); + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + return; } - } - if (flags & Visibility) { - switch (finishedWork.tag) { - case SuspenseComponent: { - var newState = finishedWork.memoizedState; + case ClassComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + return; + } + + case HostComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + return; + } + + case HostText: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + return; + } + + case HostRoot: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Update) { + { + var containerInfo = root.containerInfo; + var pendingChildren = root.pendingChildren; + + try { + replaceContainerChildren(containerInfo, pendingChildren); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + return; + } + + case HostPortal: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Update) { + { + var portal = finishedWork.stateNode; + var _containerInfo = portal.containerInfo; + var _pendingChildren = portal.pendingChildren; + + try { + replaceContainerChildren(_containerInfo, _pendingChildren); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + return; + } + + case SuspenseComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + var offscreenFiber = finishedWork.child; + + if (offscreenFiber.flags & Visibility) { + var newState = offscreenFiber.memoizedState; var isHidden = newState !== null; if (isHidden) { - var _current = finishedWork.alternate; - var wasHidden = _current !== null && _current.memoizedState !== null; + var wasHidden = + offscreenFiber.alternate !== null && + offscreenFiber.alternate.memoizedState !== null; if (!wasHidden) { // TODO: Move to passive phase markCommitTimeOfFallback(); } } - - break; } - case OffscreenComponent: { + if (flags & Update) { + try { + commitSuspenseCallback(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + attachSuspenseRetryListeners(finishedWork); + } + + return; + } + + case OffscreenComponent: { + var _wasHidden = current !== null && current.memoizedState !== null; + + { + recursivelyTraverseMutationEffects(root, finishedWork); + } + + commitReconciliationEffects(finishedWork); + + if (flags & Visibility) { var _newState = finishedWork.memoizedState; - - var _current2 = finishedWork.alternate; - - var _wasHidden = _current2 !== null && _current2.memoizedState !== null; } - } - } // The following switch statement is only concerned about placement, - // updates, and deletions. To avoid needing to add a case for every possible - // bitmap value, we remove the secondary effects from the effect tag and - // switch on that value. - var primaryFlags = flags & (Placement | Update | Hydrating); - - switch (primaryFlags) { - case Placement: { - // inserted, before any life-cycles like componentDidMount gets called. - // TODO: findDOMNode doesn't rely on this any more but isMounted does - // and isMounted is deprecated anyway so we should be able to kill this. - - finishedWork.flags &= ~Placement; - break; + return; } - case PlacementAndUpdate: { - // inserted, before any life-cycles like componentDidMount gets called. + case SuspenseListComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); - finishedWork.flags &= ~Placement; // Update + if (flags & Update) { + attachSuspenseRetryListeners(finishedWork); + } - var _current3 = finishedWork.alternate; - commitWork(_current3, finishedWork); - break; + return; } - case Hydrating: { - finishedWork.flags &= ~Hydrating; - break; + case ScopeComponent: { + return; } - case HydratingAndUpdate: { - finishedWork.flags &= ~Hydrating; // Update - - var _current4 = finishedWork.alternate; - commitWork(_current4, finishedWork); - break; + default: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + return; } + } +} - case Update: { - var _current5 = finishedWork.alternate; - commitWork(_current5, finishedWork); - break; - } +function commitReconciliationEffects(finishedWork) { + // Placement effects (insertions, reorders) can be scheduled on any fiber + // type. They needs to happen after the children effects have fired, but + // before the effects on this fiber have fired. + var flags = finishedWork.flags; + + if (flags & Placement) { + try { + commitPlacement(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. + + finishedWork.flags &= ~Placement; + } + + if (flags & Hydrating) { + finishedWork.flags &= ~Hydrating; } } @@ -18641,7 +19307,7 @@ function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { var firstChild = fiber.child; if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { - ensureCorrectReturnPointer(firstChild, fiber); + firstChild.return = fiber; nextEffect = firstChild; } else { commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); @@ -18660,7 +19326,6 @@ function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { try { commitLayoutEffectOnFiber(root, current, fiber, committedLanes); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(fiber, fiber.return, error); } @@ -18675,7 +19340,7 @@ function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { var sibling = fiber.sibling; if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); + sibling.return = fiber.return; nextEffect = sibling; return; } @@ -18684,26 +19349,51 @@ function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { } } -function commitPassiveMountEffects(root, finishedWork) { +function commitPassiveMountEffects( + root, + finishedWork, + committedLanes, + committedTransitions +) { nextEffect = finishedWork; - commitPassiveMountEffects_begin(finishedWork, root); + commitPassiveMountEffects_begin( + finishedWork, + root, + committedLanes, + committedTransitions + ); } -function commitPassiveMountEffects_begin(subtreeRoot, root) { +function commitPassiveMountEffects_begin( + subtreeRoot, + root, + committedLanes, + committedTransitions +) { while (nextEffect !== null) { var fiber = nextEffect; var firstChild = fiber.child; if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { - ensureCorrectReturnPointer(firstChild, fiber); + firstChild.return = fiber; nextEffect = firstChild; } else { - commitPassiveMountEffects_complete(subtreeRoot, root); + commitPassiveMountEffects_complete( + subtreeRoot, + root, + committedLanes, + committedTransitions + ); } } } -function commitPassiveMountEffects_complete(subtreeRoot, root) { +function commitPassiveMountEffects_complete( + subtreeRoot, + root, + committedLanes, + committedTransitions +) { while (nextEffect !== null) { var fiber = nextEffect; @@ -18711,9 +19401,13 @@ function commitPassiveMountEffects_complete(subtreeRoot, root) { setCurrentFiber(fiber); try { - commitPassiveMountOnFiber(root, fiber); + commitPassiveMountOnFiber( + root, + fiber, + committedLanes, + committedTransitions + ); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(fiber, fiber.return, error); } @@ -18728,7 +19422,7 @@ function commitPassiveMountEffects_complete(subtreeRoot, root) { var sibling = fiber.sibling; if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); + sibling.return = fiber.return; nextEffect = sibling; return; } @@ -18737,7 +19431,12 @@ function commitPassiveMountEffects_complete(subtreeRoot, root) { } } -function commitPassiveMountOnFiber(finishedRoot, finishedWork) { +function commitPassiveMountOnFiber( + finishedRoot, + finishedWork, + committedLanes, + committedTransitions +) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: @@ -18816,7 +19515,7 @@ function commitPassiveUnmountEffects_begin() { } if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { - ensureCorrectReturnPointer(child, fiber); + child.return = fiber; nextEffect = child; } else { commitPassiveUnmountEffects_complete(); @@ -18837,7 +19536,7 @@ function commitPassiveUnmountEffects_complete() { var sibling = fiber.sibling; if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); + sibling.return = fiber.return; nextEffect = sibling; return; } @@ -18887,7 +19586,7 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( // do this, still need to handle `deletedTreeCleanUpLevel` correctly.) if (child !== null) { - ensureCorrectReturnPointer(child, fiber); + child.return = fiber; nextEffect = child; } else { commitPassiveUnmountEffectsInsideOfDeletedTree_complete( @@ -18918,7 +19617,7 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( } if (sibling !== null) { - ensureCorrectReturnPointer(sibling, returnFiber); + sibling.return = returnFiber; nextEffect = sibling; return; } @@ -18946,23 +19645,6 @@ function commitPassiveUnmountInsideDeletedTreeOnFiber( break; } } -} - -var didWarnWrongReturnPointer = false; - -function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { - { - if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) { - didWarnWrongReturnPointer = true; - - error( - "Internal React error: Return pointer is inconsistent " + "with parent." - ); - } - } // TODO: Remove this assignment once we're confident that it won't break - // anything, by checking the warning logs for the above invariant - - fiber.return = expectedReturnFiber; } // TODO: Reuse reappearLayoutEffects traversal here? var COMPONENT_TYPE = 0; @@ -19086,6 +19768,7 @@ var workInProgressRootRenderTargetTime = Infinity; // How long a render is suppo // suspense heuristics and opt out of rendering more content. var RENDER_TIMEOUT_MS = 500; +var workInProgressTransitions = null; function resetRenderTimer() { workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS; @@ -19101,17 +19784,22 @@ var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; var pendingPassiveEffectsLanes = NoLanes; var pendingPassiveProfilerEffects = []; +var pendingPassiveTransitions = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; var nestedUpdateCount = 0; var rootWithNestedUpdates = null; +var isFlushingPassiveEffects = false; +var didScheduleUpdateDuringPassiveEffects = false; var NESTED_PASSIVE_UPDATE_LIMIT = 50; -var nestedPassiveUpdateCount = 0; // If two updates are scheduled within the same event, we should treat their +var nestedPassiveUpdateCount = 0; +var rootWithPassiveNestedUpdates = null; // If two updates are scheduled within the same event, we should treat their // event times as simultaneous, even if the actual clock time has advanced // between the first and second call. var currentEventTime = NoTimestamp; var currentEventTransitionLane = NoLanes; +var isRunningInsertionEffect = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -19214,10 +19902,23 @@ function requestRetryLane(fiber) { function scheduleUpdateOnFiber(fiber, lane, eventTime) { checkForNestedUpdates(); + + { + if (isRunningInsertionEffect) { + error("useInsertionEffect must not schedule updates."); + } + } + var root = markUpdateLaneFromFiberToRoot(fiber, lane); if (root === null) { return null; + } + + { + if (isFlushingPassiveEffects) { + didScheduleUpdateDuringPassiveEffects = true; + } } // Mark that the root has a pending update. markRootUpdated(root, lane, eventTime); @@ -19344,7 +20045,12 @@ function isInterleavedUpdate(fiber, lane) { // TODO: Optimize slightly by comparing to root that fiber belongs to. // Requires some refactoring. Not a big deal though since it's rare for // concurrent apps to have more than a single root. - workInProgressRoot !== null && + (workInProgressRoot !== null || // If the interleaved updates queue hasn't been cleared yet, then + // we should treat this as an interleaved update, too. This is also a + // defensive coding measure in case a new update comes in between when + // rendering has finished and when the interleaved updates are transferred + // to the main queue. + hasInterleavedUpdates()) && (fiber.mode & ConcurrentMode) !== NoMode && // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps), // then don't treat this as an interleaved update. This pattern is // accompanied by a warning but we haven't fully deprecated it yet. We can @@ -19678,7 +20384,11 @@ function finishConcurrentRender(root, exitStatus, lanes) { case RootErrored: { // We should have already attempted to retry this tree. If we reached // this point, it errored again. Commit it. - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; } @@ -19718,14 +20428,23 @@ function finishConcurrentRender(root, exitStatus, lanes) { // immediately, wait for more data to arrive. root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), msUntilTimeout ); break; } } // The work expired. Commit immediately. - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; } @@ -19756,20 +20475,33 @@ function finishConcurrentRender(root, exitStatus, lanes) { // Instead of committing the fallback immediately, wait for more data // to arrive. root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), _msUntilTimeout ); break; } } // Commit the placeholder. - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; } case RootCompleted: { // The work completed. Ready to commit. - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; } @@ -19904,7 +20636,11 @@ function performSyncWorkOnRoot(root) { var finishedWork = root.current.alternate; root.finishedWork = finishedWork; root.finishedLanes = lanes; - commitRoot(root, workInProgressRootRecoverableErrors); // Before exiting, make sure there's a callback scheduled for the next + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); // Before exiting, make sure there's a callback scheduled for the next // pending level. ensureRootIsScheduled(root, now()); @@ -20211,6 +20947,8 @@ function renderRootSync(root, lanes) { movePendingFibersToMemoized(root, lanes); } } + + workInProgressTransitions = getTransitionsForLanes(); prepareFreshStack(root, lanes); } @@ -20271,6 +21009,8 @@ function renderRootConcurrent(root, lanes) { movePendingFibersToMemoized(root, lanes); } } + + workInProgressTransitions = getTransitionsForLanes(); resetRenderTimer(); prepareFreshStack(root, lanes); } @@ -20429,7 +21169,7 @@ function completeUnitOfWork(unitOfWork) { } } -function commitRoot(root, recoverableErrors) { +function commitRoot(root, recoverableErrors, transitions) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -20438,7 +21178,12 @@ function commitRoot(root, recoverableErrors) { try { ReactCurrentBatchConfig$2.transition = null; setCurrentUpdatePriority(DiscreteEventPriority); - commitRootImpl(root, recoverableErrors, previousUpdateLanePriority); + commitRootImpl( + root, + recoverableErrors, + transitions, + previousUpdateLanePriority + ); } finally { ReactCurrentBatchConfig$2.transition = prevTransition; setCurrentUpdatePriority(previousUpdateLanePriority); @@ -20447,7 +21192,12 @@ function commitRoot(root, recoverableErrors) { return null; } -function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { +function commitRootImpl( + root, + recoverableErrors, + transitions, + renderPriorityLevel +) { do { // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which // means `flushPassiveEffects` will sometimes result in additional @@ -20515,6 +21265,13 @@ function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { ) { if (!rootDoesHavePassiveEffects) { rootDoesHavePassiveEffects = true; + // to store it in pendingPassiveTransitions until they get processed + // We need to pass this through as an argument to commitRoot + // because workInProgressTransitions might have changed between + // the previous render and commit if we throttle the commit + // with setTimeout + + pendingPassiveTransitions = transitions; scheduleCallback$1(NormalPriority, function() { flushPassiveEffects(); // This render triggered passive effects: release the root cache pool // *after* passive effects fire to avoid freeing a cache pool that may @@ -20598,6 +21355,11 @@ function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { rootDoesHavePassiveEffects = false; rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; + } else { + { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root @@ -20725,9 +21487,12 @@ function enqueuePendingPassiveProfilerEffect(fiber) { function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { return false; - } + } // Cache and clear the transitions flag + var transitions = pendingPassiveTransitions; + pendingPassiveTransitions = null; var root = rootWithPendingPassiveEffects; + var lanes = pendingPassiveEffectsLanes; rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects. // Figure out why and fix it. It's not causing any known issues (probably // because it's only used for profiling), but it's a refactor hazard. @@ -20738,10 +21503,15 @@ function flushPassiveEffectsImpl() { throw new Error("Cannot flush passive effects while already rendering."); } + { + isFlushingPassiveEffects = true; + didScheduleUpdateDuringPassiveEffects = false; + } + var prevExecutionContext = executionContext; executionContext |= CommitContext; commitPassiveUnmountEffects(root.current); - commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects + commitPassiveMountEffects(root, root.current, lanes, transitions); // TODO: Move to commitPassiveMountEffects { var profilerEffects = pendingPassiveProfilerEffects; @@ -20754,11 +21524,25 @@ function flushPassiveEffectsImpl() { } executionContext = prevExecutionContext; - flushSyncCallbacks(); // If additional passive effects were scheduled, increment a counter. If this - // exceeds the limit, we'll fire a warning. + flushSyncCallbacks(); - nestedPassiveUpdateCount = - rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; // TODO: Move to commitPassiveMountEffects + { + // If additional passive effects were scheduled, increment a counter. If this + // exceeds the limit, we'll fire a warning. + if (didScheduleUpdateDuringPassiveEffects) { + if (root === rootWithPassiveNestedUpdates) { + nestedPassiveUpdateCount++; + } else { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = root; + } + } else { + nestedPassiveUpdateCount = 0; + } + + isFlushingPassiveEffects = false; + didScheduleUpdateDuringPassiveEffects = false; + } // TODO: Move to commitPassiveMountEffects onPostCommitRoot(root); @@ -20808,6 +21592,11 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { + { + reportUncaughtErrorInDEV(error$1); + setIsRunningInsertionEffect(false); + } + if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. @@ -20932,13 +21721,42 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { ensureRootIsScheduled(root, eventTime); } } + +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState; + var retryLane = NoLane; + + if (suspenseState !== null) { + retryLane = suspenseState.retryLane; + } + + retryTimedOutBoundary(boundaryFiber, retryLane); +} function resolveRetryWakeable(boundaryFiber, wakeable) { var retryLane = NoLane; // Default var retryCache; - { - retryCache = boundaryFiber.stateNode; + switch (boundaryFiber.tag) { + case SuspenseComponent: + retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + + if (suspenseState !== null) { + retryLane = suspenseState.retryLane; + } + + break; + + case SuspenseListComponent: + retryCache = boundaryFiber.stateNode; + break; + + default: + throw new Error( + "Pinged unknown suspense boundary type. " + + "This is probably a bug in React." + ); } if (retryCache !== null) { @@ -20989,6 +21807,7 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; error( "Maximum update depth exceeded. This can happen when a component " + @@ -21092,11 +21911,13 @@ var beginWork$1; return beginWork(current, unitOfWork, lanes); } catch (originalError) { if ( - originalError !== null && - typeof originalError === "object" && - typeof originalError.then === "function" + didSuspendOrErrorWhileHydratingDEV() || + (originalError !== null && + typeof originalError === "object" && + typeof originalError.then === "function") ) { - // Don't replay promises. Treat everything else like an error. + // Don't replay promises. + // Don't replay errors if we are hydrating and have already suspended or handled an error throw originalError; } // Keep this code in sync with handleError; any changes here must have // corresponding changes there. @@ -21322,6 +22143,12 @@ function warnIfSuspenseResolutionNotWrappedWithActDEV(root) { } } +function setIsRunningInsertionEffect(isRunning) { + { + isRunningInsertionEffect = isRunning; + } +} + /* eslint-disable react-internal/prod-error-codes */ var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. @@ -22456,7 +23283,8 @@ function createFiberRoot( isDehydrated: hydrate, cache: null, // not enabled yet - transitions: null + transitions: null, + pendingSuspenseBoundaries: null }; uninitializedFiber.memoizedState = _initialState; } @@ -22465,7 +23293,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.0.0-34aa5cfe0-20220329"; +var ReactVersion = "18.2.0-next-d300cebde-20220601"; function createPortal( children, diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.js b/Libraries/Renderer/implementations/ReactFabric-prod.js index 679ac7c7a33..9f83af5c81e 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactFabric-prod * @preventMunge - * @generated SignedSource<<3337b7b8b4a72069e657cf2646bcff44>> + * @generated SignedSource<> */ "use strict"; @@ -1017,7 +1017,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_215 = { +var injectedNamesToPlugins$jscomp$inline_218 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1063,33 +1063,33 @@ var injectedNamesToPlugins$jscomp$inline_215 = { } } }, - isOrderingDirty$jscomp$inline_216 = !1, - pluginName$jscomp$inline_217; -for (pluginName$jscomp$inline_217 in injectedNamesToPlugins$jscomp$inline_215) + isOrderingDirty$jscomp$inline_219 = !1, + pluginName$jscomp$inline_220; +for (pluginName$jscomp$inline_220 in injectedNamesToPlugins$jscomp$inline_218) if ( - injectedNamesToPlugins$jscomp$inline_215.hasOwnProperty( - pluginName$jscomp$inline_217 + injectedNamesToPlugins$jscomp$inline_218.hasOwnProperty( + pluginName$jscomp$inline_220 ) ) { - var pluginModule$jscomp$inline_218 = - injectedNamesToPlugins$jscomp$inline_215[pluginName$jscomp$inline_217]; + var pluginModule$jscomp$inline_221 = + injectedNamesToPlugins$jscomp$inline_218[pluginName$jscomp$inline_220]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_217) || - namesToPlugins[pluginName$jscomp$inline_217] !== - pluginModule$jscomp$inline_218 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_220) || + namesToPlugins[pluginName$jscomp$inline_220] !== + pluginModule$jscomp$inline_221 ) { - if (namesToPlugins[pluginName$jscomp$inline_217]) + if (namesToPlugins[pluginName$jscomp$inline_220]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_217 + "`.") + (pluginName$jscomp$inline_220 + "`.") ); namesToPlugins[ - pluginName$jscomp$inline_217 - ] = pluginModule$jscomp$inline_218; - isOrderingDirty$jscomp$inline_216 = !0; + pluginName$jscomp$inline_220 + ] = pluginModule$jscomp$inline_221; + isOrderingDirty$jscomp$inline_219 = !0; } } -isOrderingDirty$jscomp$inline_216 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_219 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -1841,6 +1841,12 @@ function getLanesToRetrySynchronouslyOnError(root) { root = root.pendingLanes & -1073741825; return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; } +function claimNextTransitionLane() { + var lane = nextTransitionLane; + nextTransitionLane <<= 1; + 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64); + return lane; +} function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; @@ -2189,7 +2195,28 @@ function flushSyncCallbacks() { } return null; } -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +var forkStack = [], + forkStackIndex = 0, + treeForkProvider = null, + idStack = [], + idStackIndex = 0, + treeContextProvider = null; +function popTreeContext(workInProgress) { + for (; workInProgress === treeForkProvider; ) + (treeForkProvider = forkStack[--forkStackIndex]), + (forkStack[forkStackIndex] = null), + --forkStackIndex, + (forkStack[forkStackIndex] = null); + for (; workInProgress === treeContextProvider; ) + (treeContextProvider = idStack[--idStackIndex]), + (idStack[idStackIndex] = null), + --idStackIndex, + (idStack[idStackIndex] = null), + --idStackIndex, + (idStack[idStackIndex] = null); +} +var hydrationErrors = null, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function shallowEqual(objA, objB) { if (objectIs(objA, objB)) return !0; if ( @@ -2334,9 +2361,7 @@ function enqueueUpdate(fiber, update) { var updateQueue = fiber.updateQueue; null !== updateQueue && ((updateQueue = updateQueue.shared), - null !== workInProgressRoot && - 0 !== (fiber.mode & 1) && - 0 === (executionContext & 2) + isInterleavedUpdate(fiber) ? ((fiber = updateQueue.interleaved), null === fiber ? ((update.next = update), @@ -2704,26 +2729,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var forkStack = [], - forkStackIndex = 0, - treeForkProvider = null, - idStack = [], - idStackIndex = 0, - treeContextProvider = null; -function popTreeContext(workInProgress) { - for (; workInProgress === treeForkProvider; ) - (treeForkProvider = forkStack[--forkStackIndex]), - (forkStack[forkStackIndex] = null), - --forkStackIndex, - (forkStack[forkStackIndex] = null); - for (; workInProgress === treeContextProvider; ) - (treeContextProvider = idStack[--idStackIndex]), - (idStack[idStackIndex] = null), - --idStackIndex, - (idStack[idStackIndex] = null), - --idStackIndex, - (idStack[idStackIndex] = null); -} function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2786,6 +2791,10 @@ function throwOnInvalidObjectType(returnFiber, newChild) { "). If you meant to render a collection of children, use an array instead." ); } +function resolveLazy(lazyType) { + var init = lazyType._init; + return init(lazyType._payload); +} function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { @@ -2858,7 +2867,14 @@ function ChildReconciler(shouldTrackSideEffects) { lanes, element.key ); - if (null !== current && current.elementType === elementType) + if ( + null !== current && + (current.elementType === elementType || + ("object" === typeof elementType && + null !== elementType && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === current.type)) + ) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2949,6 +2965,9 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild.return = returnFiber), newChild ); + case REACT_LAZY_TYPE: + var init = newChild._init; + return createChild(returnFiber, init(newChild._payload), lanes); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -2984,6 +3003,11 @@ function ChildReconciler(shouldTrackSideEffects) { return newChild.key === key ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; + case REACT_LAZY_TYPE: + return ( + (key = newChild._init), + updateSlot(returnFiber, oldFiber, key(newChild._payload), lanes) + ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key @@ -3026,6 +3050,15 @@ function ChildReconciler(shouldTrackSideEffects) { ) || null), updatePortal(returnFiber, existingChildren, newChild, lanes) ); + case REACT_LAZY_TYPE: + var init = newChild._init; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + init(newChild._payload), + lanes + ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -3203,7 +3236,12 @@ function ChildReconciler(shouldTrackSideEffects) { }); return iteratorFn; } - return function(returnFiber, currentFirstChild, newChild, lanes) { + function reconcileChildFibers( + returnFiber, + currentFirstChild, + newChild, + lanes + ) { "object" === typeof newChild && null !== newChild && newChild.type === REACT_FRAGMENT_TYPE && @@ -3231,7 +3269,13 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; break a; } - } else if (child.elementType === key) { + } else if ( + child.elementType === key || + ("object" === typeof key && + null !== key && + key.$$typeof === REACT_LAZY_TYPE && + resolveLazy(key) === child.type) + ) { deleteRemainingChildren(returnFiber, child.sibling); currentFirstChild = useFiber(child, newChild.props); currentFirstChild.ref = coerceRef( @@ -3312,6 +3356,16 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; } return placeSingleChild(returnFiber); + case REACT_LAZY_TYPE: + return ( + (child = newChild._init), + reconcileChildFibers( + returnFiber, + currentFirstChild, + child(newChild._payload), + lanes + ) + ); } if (isArrayImpl(newChild)) return reconcileChildrenArray( @@ -3347,7 +3401,8 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber)) : deleteRemainingChildren(returnFiber, currentFirstChild); - }; + } + return reconcileChildFibers; } var reconcileChildFibers = ChildReconciler(!0), mountChildFibers = ChildReconciler(!1), @@ -3834,6 +3889,19 @@ function updateMemo(nextCreate, deps) { hook.memoizedState = [nextCreate, deps]; return nextCreate; } +function updateDeferredValueImpl(hook, prevValue, value) { + if (0 === (renderLanes & 21)) + return ( + hook.baseState && ((hook.baseState = !1), (didReceiveUpdate = !0)), + (hook.memoizedState = value) + ); + objectIs(value, prevValue) || + ((value = claimNextTransitionLane()), + (currentlyRenderingFiber$1.lanes |= value), + (workInProgressRootSkippedLanes |= value), + (hook.baseState = !0)); + return prevValue; +} function startTransition(setPending, callback) { var previousPriority = currentUpdatePriority; currentUpdatePriority = @@ -3915,9 +3983,7 @@ function enqueueRenderPhaseUpdate(queue, update) { queue.pending = update; } function enqueueUpdate$1(fiber, queue, update) { - null !== workInProgressRoot && - 0 !== (fiber.mode & 1) && - 0 === (executionContext & 2) + isInterleavedUpdate(fiber) ? ((fiber = queue.interleaved), null === fiber ? ((update.next = update), @@ -4022,29 +4088,14 @@ var ContextOnlyDispatcher = { useState: mountState, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _mountState = mountState(value), - prevValue = _mountState[0], - setValue = _mountState[1]; - mountEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + return (mountWorkInProgressHook().memoizedState = value); }, useTransition: function() { - var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = startTransition.bind(null, _mountState2[1]); - mountWorkInProgressHook().memoizedState = _mountState2; - return [isPending, _mountState2]; + var _mountState = mountState(!1), + isPending = _mountState[0]; + _mountState = startTransition.bind(null, _mountState[1]); + mountWorkInProgressHook().memoizedState = _mountState; + return [isPending, _mountState]; }, useMutableSource: function() {}, useSyncExternalStore: function(subscribe, getSnapshot) { @@ -4098,22 +4149,8 @@ var ContextOnlyDispatcher = { }, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _updateState = updateReducer(basicStateReducer), - prevValue = _updateState[0], - setValue = _updateState[1]; - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + return updateDeferredValueImpl(hook, currentHook.memoizedState, value); }, useTransition: function() { var isPending = updateReducer(basicStateReducer)[0], @@ -4141,22 +4178,10 @@ var ContextOnlyDispatcher = { }, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + return null === currentHook + ? (hook.memoizedState = value) + : updateDeferredValueImpl(hook, currentHook.memoizedState, value); }, useTransition: function() { var isPending = rerenderReducer(basicStateReducer)[0], @@ -4259,504 +4284,6 @@ function attachPingListener(root, wakeable, lanes) { (root = pingSuspendedRoot.bind(null, root, wakeable, lanes)), wakeable.then(root, root)); } -function hadNoMutationsEffects(current, completedWork) { - if (null !== current && current.child === completedWork.child) return !0; - if (0 !== (completedWork.flags & 16)) return !1; - for (current = completedWork.child; null !== current; ) { - if (0 !== (current.flags & 12854) || 0 !== (current.subtreeFlags & 12854)) - return !1; - current = current.sibling; - } - return !0; -} -var appendAllChildren, updateHostContainer, updateHostComponent, updateHostText; -appendAllChildren = function( - parent, - workInProgress, - needsVisibilityToggle, - isHidden -) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag) { - var instance = node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNode(parent.node, instance.node); - } else if (6 === node.tag) { - instance = node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNode(parent.node, instance.node); - } else if (4 !== node.tag) - if (22 === node.tag && null !== node.memoizedState) - (instance = node.child), - null !== instance && (instance.return = node), - appendAllChildren(parent, node, !0, !0); - else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -}; -function appendAllChildrenToContainer( - containerChildSet, - workInProgress, - needsVisibilityToggle, - isHidden -) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag) { - var instance = node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (6 === node.tag) { - instance = node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (4 !== node.tag) - if (22 === node.tag && null !== node.memoizedState) - (instance = node.child), - null !== instance && (instance.return = node), - appendAllChildrenToContainer(containerChildSet, node, !0, !0); - else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -} -updateHostContainer = function(current, workInProgress) { - var portalOrRoot = workInProgress.stateNode; - if (!hadNoMutationsEffects(current, workInProgress)) { - current = portalOrRoot.containerInfo; - var newChildSet = createChildNodeSet(current); - appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); - portalOrRoot.pendingChildren = newChildSet; - workInProgress.flags |= 4; - completeRoot(current, newChildSet); - } -}; -updateHostComponent = function(current, workInProgress, type, newProps) { - type = current.stateNode; - var oldProps = current.memoizedProps; - if ( - (current = hadNoMutationsEffects(current, workInProgress)) && - oldProps === newProps - ) - workInProgress.stateNode = type; - else { - var recyclableInstance = workInProgress.stateNode; - requiredContext(contextStackCursor$1.current); - var updatePayload = null; - oldProps !== newProps && - ((oldProps = diffProperties( - null, - oldProps, - newProps, - recyclableInstance.canonical.viewConfig.validAttributes - )), - (recyclableInstance.canonical.currentProps = newProps), - (updatePayload = oldProps)); - current && null === updatePayload - ? (workInProgress.stateNode = type) - : ((newProps = updatePayload), - (oldProps = type.node), - (type = { - node: current - ? null !== newProps - ? cloneNodeWithNewProps(oldProps, newProps) - : cloneNode(oldProps) - : null !== newProps - ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) - : cloneNodeWithNewChildren(oldProps), - canonical: type.canonical - }), - (workInProgress.stateNode = type), - current - ? (workInProgress.flags |= 4) - : appendAllChildren(type, workInProgress, !1, !1)); - } -}; -updateHostText = function(current, workInProgress, oldText, newText) { - oldText !== newText - ? ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.flags |= 4)) - : (workInProgress.stateNode = current.stateNode); -}; -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var lastTailNode$35 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$35 = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === lastTailNode$35 - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (lastTailNode$35.sibling = null); - } -} -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - for (var child$36 = completedWork.child; null !== child$36; ) - (newChildLanes |= child$36.lanes | child$36.childLanes), - (subtreeFlags |= child$36.subtreeFlags & 14680064), - (subtreeFlags |= child$36.flags & 14680064), - (child$36.return = completedWork), - (child$36 = child$36.sibling); - else - for (child$36 = completedWork.child; null !== child$36; ) - (newChildLanes |= child$36.lanes | child$36.childLanes), - (subtreeFlags |= child$36.subtreeFlags), - (subtreeFlags |= child$36.flags), - (child$36.return = completedWork), - (child$36 = child$36.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; - popTreeContext(workInProgress); - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); - case 3: - return ( - (newProps = workInProgress.stateNode), - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - resetWorkInProgressVersions(), - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)), - (null !== current && null !== current.child) || - null === current || - (current.memoizedState.isDehydrated && - 0 === (workInProgress.flags & 256)) || - (workInProgress.flags |= 1024), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 5: - popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent( - current, - workInProgress, - type, - newProps, - renderLanes - ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 512); - else { - if (!newProps) { - if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - bubbleProperties(workInProgress); - return null; - } - requiredContext(contextStackCursor$1.current); - current = nextReactTag; - nextReactTag += 2; - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - renderLanes = createNode( - current, - type.uiViewClassName, - renderLanes, - updatePayload, - workInProgress - ); - current = new ReactFabricHostComponent( - current, - type, - newProps, - workInProgress - ); - current = { node: renderLanes, canonical: current }; - appendAllChildren(current, workInProgress, !1, !1); - workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 512); - } - bubbleProperties(workInProgress); - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - renderLanes = requiredContext(contextStackCursor$1.current); - workInProgress.stateNode = createTextInstance( - newProps, - current, - renderLanes, - workInProgress - ); - } - bubbleProperties(workInProgress); - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) - return (workInProgress.lanes = renderLanes), workInProgress; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - null === newProps || - renderLanes || - ((workInProgress.child.flags |= 8192), - 0 !== (workInProgress.mode & 1) && - (null === current || 0 !== (suspenseStackCursor.current & 1) - ? 0 === workInProgressRootExitStatus && - (workInProgressRootExitStatus = 3) - : renderDidSuspendDelayIfPossible())); - null !== workInProgress.updateQueue && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); - return null; - case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); - case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); - case 19: - pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; - if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); - else { - if ( - 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (type = current), - (renderLanes.flags &= 14680066), - (updatePayload = renderLanes.alternate), - null === updatePayload - ? ((renderLanes.childLanes = 0), - (renderLanes.lanes = type), - (renderLanes.child = null), - (renderLanes.subtreeFlags = 0), - (renderLanes.memoizedProps = null), - (renderLanes.memoizedState = null), - (renderLanes.updateQueue = null), - (renderLanes.dependencies = null), - (renderLanes.stateNode = null)) - : ((renderLanes.childLanes = updatePayload.childLanes), - (renderLanes.lanes = updatePayload.lanes), - (renderLanes.child = updatePayload.child), - (renderLanes.subtreeFlags = 0), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = - updatePayload.memoizedProps), - (renderLanes.memoizedState = - updatePayload.memoizedState), - (renderLanes.updateQueue = updatePayload.updateQueue), - (renderLanes.type = updatePayload.type), - (type = updatePayload.dependencies), - (renderLanes.dependencies = - null === type - ? null - : { - lanes: type.lanes, - firstContext: type.firstContext - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== type.tail && - now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && - !updatePayload.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now() - type.renderingStartTime > - workInProgressRootRenderTargetTime && - 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - type.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (type.last = updatePayload)); - } - if (null !== type.tail) - return ( - (workInProgress = type.tail), - (type.rendering = workInProgress), - (type.tail = workInProgress.sibling), - (type.renderingStartTime = now()), - (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), - workInProgress - ); - bubbleProperties(workInProgress); - return null; - case 22: - case 23: - return ( - popRenderLanes(), - (newProps = null !== workInProgress.memoizedState), - null !== current && - (null !== current.memoizedState) !== newProps && - (workInProgress.flags |= 8192), - newProps && 0 !== (workInProgress.mode & 1) - ? 0 !== (subtreeRenderLanes & 1073741824) && - bubbleProperties(workInProgress) - : bubbleProperties(workInProgress), - null - ); - case 24: - return null; - case 25: - return null; - } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); -} var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { @@ -4859,18 +4386,24 @@ function updateSimpleMemoComponent( nextProps, renderLanes ) { - if ( - null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes))) - 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); - else - return ( - (workInProgress.lanes = current.lanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); + if (null !== current) { + var prevProps = current.memoizedProps; + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref + ) + if ( + ((didReceiveUpdate = !1), + (workInProgress.pendingProps = nextProps = prevProps), + 0 !== (current.lanes & renderLanes)) + ) + 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); + else + return ( + (workInProgress.lanes = current.lanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + } return updateFunctionComponent( current, workInProgress, @@ -4885,7 +4418,11 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { prevState = null !== current ? current.memoizedState : null; if ("hidden" === nextProps.mode) if (0 === (workInProgress.mode & 1)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + (workInProgress.memoizedState = { + baseLanes: 0, + cachePool: null, + transitions: null + }), push(subtreeRenderLanesCursor, subtreeRenderLanes), (subtreeRenderLanes |= renderLanes); else { @@ -4898,14 +4435,19 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { (workInProgress.lanes = workInProgress.childLanes = 1073741824), (workInProgress.memoizedState = { baseLanes: current, - cachePool: null + cachePool: null, + transitions: null }), (workInProgress.updateQueue = null), push(subtreeRenderLanesCursor, subtreeRenderLanes), (subtreeRenderLanes |= current), null ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + workInProgress.memoizedState = { + baseLanes: 0, + cachePool: null, + transitions: null + }; nextProps = null !== prevState ? prevState.baseLanes : renderLanes; push(subtreeRenderLanesCursor, subtreeRenderLanes); subtreeRenderLanes |= nextProps; @@ -4920,7 +4462,7 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef$1(current, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( (null === current && null !== ref) || @@ -4972,10 +4514,7 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderLanes); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)), + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), constructClassInstance(workInProgress, Component, nextProps), mountClassInstance(workInProgress, Component, nextProps, renderLanes), (nextProps = !0); @@ -5169,7 +4708,7 @@ function finishClassComponent( hasContext, renderLanes ) { - markRef$1(current, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( @@ -5215,14 +4754,15 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, treeContext: null, retryLane: 0 }; function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: null }; + return { baseLanes: renderLanes, cachePool: null, transitions: null }; } function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, + didSuspend = 0 !== (workInProgress.flags & 128), JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || + (JSCompiler_temp = didSuspend) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 @@ -5232,167 +4772,297 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext |= 1; push(suspenseStackCursor, suspenseContext & 1); if (null === current) { - suspenseContext = nextProps.children; - current = nextProps.fallback; - if (showFallback) + current = workInProgress.memoizedState; + if (null !== current && null !== current.dehydrated) return ( - (showFallback = workInProgress.mode), - (nextProps = workInProgress.child), - (suspenseContext = { mode: "hidden", children: suspenseContext }), - 0 === (showFallback & 1) && null !== nextProps - ? ((nextProps.childLanes = 0), - (nextProps.pendingProps = suspenseContext)) - : (nextProps = createFiberFromOffscreen( - suspenseContext, - showFallback, + 0 === (workInProgress.mode & 1) + ? (workInProgress.lanes = 1) + : shim$1() + ? (workInProgress.lanes = 8) + : (workInProgress.lanes = 1073741824), + null + ); + didSuspend = nextProps.children; + current = nextProps.fallback; + return showFallback + ? ((nextProps = workInProgress.mode), + (showFallback = workInProgress.child), + (didSuspend = { mode: "hidden", children: didSuspend }), + 0 === (nextProps & 1) && null !== showFallback + ? ((showFallback.childLanes = 0), + (showFallback.pendingProps = didSuspend)) + : (showFallback = createFiberFromOffscreen( + didSuspend, + nextProps, 0, null )), (current = createFiberFromFragment( current, - showFallback, + nextProps, renderLanes, null )), - (nextProps.return = workInProgress), + (showFallback.return = workInProgress), (current.return = workInProgress), - (nextProps.sibling = current), - (workInProgress.child = nextProps), + (showFallback.sibling = current), + (workInProgress.child = showFallback), (workInProgress.child.memoizedState = mountSuspenseOffscreenState( renderLanes )), (workInProgress.memoizedState = SUSPENDED_MARKER), - current - ); - renderLanes = createFiberFromOffscreen( - { mode: "visible", children: suspenseContext }, - workInProgress.mode, - 0, - null - ); - renderLanes.return = workInProgress; - return (workInProgress.child = renderLanes); + current) + : mountSuspensePrimaryChildren(workInProgress, didSuspend); } - if (null !== current.memoizedState) { - if (showFallback) - return ( - (showFallback = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (nextProps = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (nextProps.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (nextProps.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - showFallback - ); - renderLanes = updateSuspensePrimaryChildren( + suspenseContext = current.memoizedState; + if ( + null !== suspenseContext && + ((JSCompiler_temp = suspenseContext.dehydrated), null !== JSCompiler_temp) + ) + return updateDehydratedSuspenseComponent( current, workInProgress, - nextProps.children, + didSuspend, + nextProps, + JSCompiler_temp, + suspenseContext, renderLanes ); - workInProgress.memoizedState = null; - return renderLanes; + if (showFallback) { + showFallback = nextProps.fallback; + didSuspend = workInProgress.mode; + suspenseContext = current.child; + JSCompiler_temp = suspenseContext.sibling; + var primaryChildProps = { mode: "hidden", children: nextProps.children }; + 0 === (didSuspend & 1) && workInProgress.child !== suspenseContext + ? ((nextProps = workInProgress.child), + (nextProps.childLanes = 0), + (nextProps.pendingProps = primaryChildProps), + (workInProgress.deletions = null)) + : ((nextProps = createWorkInProgress(suspenseContext, primaryChildProps)), + (nextProps.subtreeFlags = suspenseContext.subtreeFlags & 14680064)); + null !== JSCompiler_temp + ? (showFallback = createWorkInProgress(JSCompiler_temp, showFallback)) + : ((showFallback = createFiberFromFragment( + showFallback, + didSuspend, + renderLanes, + null + )), + (showFallback.flags |= 2)); + showFallback.return = workInProgress; + nextProps.return = workInProgress; + nextProps.sibling = showFallback; + workInProgress.child = nextProps; + nextProps = showFallback; + showFallback = workInProgress.child; + didSuspend = current.child.memoizedState; + didSuspend = + null === didSuspend + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: didSuspend.baseLanes | renderLanes, + cachePool: null, + transitions: didSuspend.transitions + }; + showFallback.memoizedState = didSuspend; + showFallback.childLanes = current.childLanes & ~renderLanes; + workInProgress.memoizedState = SUSPENDED_MARKER; + return nextProps; } - if (showFallback) - return ( - (showFallback = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (nextProps = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (nextProps.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (nextProps.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - showFallback - ); - renderLanes = updateSuspensePrimaryChildren( - current, - workInProgress, - nextProps.children, - renderLanes - ); - workInProgress.memoizedState = null; - return renderLanes; -} -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - primaryChildren = createWorkInProgress(currentPrimaryChildFragment, { + showFallback = current.child; + current = showFallback.sibling; + nextProps = createWorkInProgress(showFallback, { mode: "visible", - children: primaryChildren + children: nextProps.children }); - 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); - primaryChildren.return = workInProgress; - primaryChildren.sibling = null; + 0 === (workInProgress.mode & 1) && (nextProps.lanes = renderLanes); + nextProps.return = workInProgress; + nextProps.sibling = null; null !== current && ((renderLanes = workInProgress.deletions), null === renderLanes ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) : renderLanes.push(current)); + workInProgress.child = nextProps; + workInProgress.memoizedState = null; + return nextProps; +} +function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { + primaryChildren = createFiberFromOffscreen( + { mode: "visible", children: primaryChildren }, + workInProgress.mode, + 0, + null + ); + primaryChildren.return = workInProgress; return (workInProgress.child = primaryChildren); } -function updateSuspenseFallbackChildren( +function retrySuspenseComponentWithoutHydrating( current, workInProgress, - primaryChildren, - fallbackChildren, + renderLanes, + recoverableError +) { + null !== recoverableError && + (null === hydrationErrors + ? (hydrationErrors = [recoverableError]) + : hydrationErrors.push(recoverableError)); + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + current = mountSuspensePrimaryChildren( + workInProgress, + workInProgress.pendingProps.children + ); + current.flags |= 2; + workInProgress.memoizedState = null; + return current; +} +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + nextProps, + suspenseInstance, + suspenseState, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, - primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current - ? ((primaryChildren = workInProgress.child), - (primaryChildren.childLanes = 0), - (primaryChildren.pendingProps = primaryChildProps), - (workInProgress.deletions = null)) - : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 14680064)); - null !== currentFallbackChildFragment - ? (fallbackChildren = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - )) - : ((fallbackChildren = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, + if (didSuspend) { + if (workInProgress.flags & 256) + return ( + (workInProgress.flags &= -257), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + Error( + "There was an error while hydrating this Suspense boundary. Switched to client rendering." + ) + ) + ); + if (null !== workInProgress.memoizedState) + return ( + (workInProgress.child = current.child), + (workInProgress.flags |= 128), null - )), - (fallbackChildren.flags |= 2)); - fallbackChildren.return = workInProgress; - primaryChildren.return = workInProgress; - primaryChildren.sibling = fallbackChildren; - workInProgress.child = primaryChildren; - return fallbackChildren; + ); + suspenseState = nextProps.fallback; + didSuspend = workInProgress.mode; + nextProps = createFiberFromOffscreen( + { mode: "visible", children: nextProps.children }, + didSuspend, + 0, + null + ); + suspenseState = createFiberFromFragment( + suspenseState, + didSuspend, + renderLanes, + null + ); + suspenseState.flags |= 2; + nextProps.return = workInProgress; + suspenseState.return = workInProgress; + nextProps.sibling = suspenseState; + workInProgress.child = nextProps; + 0 !== (workInProgress.mode & 1) && + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return suspenseState; + } + if (0 === (workInProgress.mode & 1)) + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + if (shim$1()) + return ( + (suspenseState = shim$1().errorMessage), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + suspenseState + ? Error(suspenseState) + : Error( + "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." + ) + ) + ); + didSuspend = 0 !== (renderLanes & current.childLanes); + if (didReceiveUpdate || didSuspend) { + nextProps = workInProgressRoot; + if (null !== nextProps) { + switch (renderLanes & -renderLanes) { + case 4: + didSuspend = 2; + break; + case 16: + didSuspend = 8; + break; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + didSuspend = 32; + break; + case 536870912: + didSuspend = 268435456; + break; + default: + didSuspend = 0; + } + nextProps = + 0 !== (didSuspend & (nextProps.suspendedLanes | renderLanes)) + ? 0 + : didSuspend; + 0 !== nextProps && + nextProps !== suspenseState.retryLane && + ((suspenseState.retryLane = nextProps), + scheduleUpdateOnFiber(current, nextProps, -1)); + } + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + Error( + "This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition." + ) + ); + } + if (shim$1()) + return ( + (workInProgress.flags |= 128), + (workInProgress.child = current.child), + retryDehydratedSuspenseBoundary.bind(null, current), + shim$1(), + null + ); + current = mountSuspensePrimaryChildren(workInProgress, nextProps.children); + current.flags |= 4096; + return current; } function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes |= renderLanes; @@ -5511,6 +5181,13 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { } return workInProgress.child; } +function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + 0 === (workInProgress.mode & 1) && + null !== current && + ((current.alternate = null), + (workInProgress.alternate = null), + (workInProgress.flags |= 2)); +} function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); workInProgressRootSkippedLanes |= workInProgress.lanes; @@ -5558,7 +5235,14 @@ function attemptEarlyBailoutIfNoScheduledUpdate( context._currentValue2 = nextValue; break; case 13: - if (null !== workInProgress.memoizedState) { + context = workInProgress.memoizedState; + if (null !== context) { + if (null !== context.dehydrated) + return ( + push(suspenseStackCursor, suspenseStackCursor.current & 1), + (workInProgress.flags |= 128), + null + ); if (0 !== (renderLanes & workInProgress.child.childLanes)) return updateSuspenseComponent(current, workInProgress, renderLanes); push(suspenseStackCursor, suspenseStackCursor.current & 1); @@ -5599,6 +5283,532 @@ function attemptEarlyBailoutIfNoScheduledUpdate( } return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } +function hadNoMutationsEffects(current, completedWork) { + if (null !== current && current.child === completedWork.child) return !0; + if (0 !== (completedWork.flags & 16)) return !1; + for (current = completedWork.child; null !== current; ) { + if (0 !== (current.flags & 12854) || 0 !== (current.subtreeFlags & 12854)) + return !1; + current = current.sibling; + } + return !0; +} +var appendAllChildren, + updateHostContainer, + updateHostComponent$1, + updateHostText$1; +appendAllChildren = function( + parent, + workInProgress, + needsVisibilityToggle, + isHidden +) { + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag) { + var instance = node.stateNode; + needsVisibilityToggle && + isHidden && + (instance = cloneHiddenInstance(instance)); + appendChildNode(parent.node, instance.node); + } else if (6 === node.tag) { + instance = node.stateNode; + if (needsVisibilityToggle && isHidden) + throw Error("Not yet implemented."); + appendChildNode(parent.node, instance.node); + } else if (4 !== node.tag) + if (22 === node.tag && null !== node.memoizedState) + (instance = node.child), + null !== instance && (instance.return = node), + appendAllChildren(parent, node, !0, !0); + else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +}; +function appendAllChildrenToContainer( + containerChildSet, + workInProgress, + needsVisibilityToggle, + isHidden +) { + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag) { + var instance = node.stateNode; + needsVisibilityToggle && + isHidden && + (instance = cloneHiddenInstance(instance)); + appendChildNodeToSet(containerChildSet, instance.node); + } else if (6 === node.tag) { + instance = node.stateNode; + if (needsVisibilityToggle && isHidden) + throw Error("Not yet implemented."); + appendChildNodeToSet(containerChildSet, instance.node); + } else if (4 !== node.tag) + if (22 === node.tag && null !== node.memoizedState) + (instance = node.child), + null !== instance && (instance.return = node), + appendAllChildrenToContainer(containerChildSet, node, !0, !0); + else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} +updateHostContainer = function(current, workInProgress) { + var portalOrRoot = workInProgress.stateNode; + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); + appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); + portalOrRoot.pendingChildren = newChildSet; + workInProgress.flags |= 4; + completeRoot(current, newChildSet); + } +}; +updateHostComponent$1 = function(current, workInProgress, type, newProps) { + type = current.stateNode; + var oldProps = current.memoizedProps; + if ( + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps + ) + workInProgress.stateNode = type; + else { + var recyclableInstance = workInProgress.stateNode; + requiredContext(contextStackCursor$1.current); + var updatePayload = null; + oldProps !== newProps && + ((oldProps = diffProperties( + null, + oldProps, + newProps, + recyclableInstance.canonical.viewConfig.validAttributes + )), + (recyclableInstance.canonical.currentProps = newProps), + (updatePayload = oldProps)); + current && null === updatePayload + ? (workInProgress.stateNode = type) + : ((newProps = updatePayload), + (oldProps = type.node), + (type = { + node: current + ? null !== newProps + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) + : null !== newProps + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), + canonical: type.canonical + }), + (workInProgress.stateNode = type), + current + ? (workInProgress.flags |= 4) + : appendAllChildren(type, workInProgress, !1, !1)); + } +}; +updateHostText$1 = function(current, workInProgress, oldText, newText) { + oldText !== newText + ? ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.flags |= 4)) + : (workInProgress.stateNode = current.stateNode); +}; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var lastTailNode$60 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$60 = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === lastTailNode$60 + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (lastTailNode$60.sibling = null); + } +} +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$61 = completedWork.child; null !== child$61; ) + (newChildLanes |= child$61.lanes | child$61.childLanes), + (subtreeFlags |= child$61.subtreeFlags & 14680064), + (subtreeFlags |= child$61.flags & 14680064), + (child$61.return = completedWork), + (child$61 = child$61.sibling); + else + for (child$61 = completedWork.child; null !== child$61; ) + (newChildLanes |= child$61.lanes | child$61.childLanes), + (subtreeFlags |= child$61.subtreeFlags), + (subtreeFlags |= child$61.flags), + (child$61.return = completedWork), + (child$61 = child$61.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + popTreeContext(workInProgress); + switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return bubbleProperties(workInProgress), null; + case 1: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 3: + return ( + (renderLanes = workInProgress.stateNode), + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + resetWorkInProgressVersions(), + renderLanes.pendingContext && + ((renderLanes.context = renderLanes.pendingContext), + (renderLanes.pendingContext = null)), + (null !== current && null !== current.child) || + null === current || + (current.memoizedState.isDehydrated && + 0 === (workInProgress.flags & 256)) || + ((workInProgress.flags |= 1024), + null !== hydrationErrors && + (queueRecoverableErrors(hydrationErrors), + (hydrationErrors = null))), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 5: + popHostContext(workInProgress); + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + renderLanes + ), + current.ref !== workInProgress.ref && (workInProgress.flags |= 512); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + bubbleProperties(workInProgress); + return null; + } + requiredContext(contextStackCursor$1.current); + current = nextReactTag; + nextReactTag += 2; + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + type.validAttributes + ); + renderLanes = createNode( + current, + type.uiViewClassName, + renderLanes, + updatePayload, + workInProgress + ); + current = new ReactFabricHostComponent( + current, + type, + newProps, + workInProgress + ); + current = { node: renderLanes, canonical: current }; + appendAllChildren(current, workInProgress, !1, !1); + workInProgress.stateNode = current; + null !== workInProgress.ref && (workInProgress.flags |= 512); + } + bubbleProperties(workInProgress); + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText$1( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + renderLanes = requiredContext(contextStackCursor$1.current); + workInProgress.stateNode = createTextInstance( + newProps, + current, + renderLanes, + workInProgress + ); + } + bubbleProperties(workInProgress); + return null; + case 13: + pop(suspenseStackCursor); + newProps = workInProgress.memoizedState; + if ( + null === current || + (null !== current.memoizedState && + null !== current.memoizedState.dehydrated) + ) { + if (null !== newProps && null !== newProps.dehydrated) { + if (null === current) { + throw Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ); + throw Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + 0 === (workInProgress.flags & 128) && + (workInProgress.memoizedState = null); + workInProgress.flags |= 4; + bubbleProperties(workInProgress); + type = !1; + } else + null !== hydrationErrors && + (queueRecoverableErrors(hydrationErrors), (hydrationErrors = null)), + (type = !0); + if (!type) return workInProgress.flags & 65536 ? workInProgress : null; + } + if (0 !== (workInProgress.flags & 128)) + return (workInProgress.lanes = renderLanes), workInProgress; + renderLanes = null !== newProps; + renderLanes !== (null !== current && null !== current.memoizedState) && + renderLanes && + ((workInProgress.child.flags |= 8192), + 0 !== (workInProgress.mode & 1) && + (null === current || 0 !== (suspenseStackCursor.current & 1) + ? 0 === workInProgressRootExitStatus && + (workInProgressRootExitStatus = 3) + : renderDidSuspendDelayIfPossible())); + null !== workInProgress.updateQueue && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + return null; + case 4: + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 10: + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor); + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; + if (null === updatePayload) + if (newProps) cutOffTailIfNeeded(type, !1); + else { + if ( + 0 !== workInProgressRootExitStatus || + (null !== current && 0 !== (current.flags & 128)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)); + workInProgress.subtreeFlags = 0; + current = renderLanes; + for (renderLanes = workInProgress.child; null !== renderLanes; ) + (newProps = renderLanes), + (type = current), + (newProps.flags &= 14680066), + (updatePayload = newProps.alternate), + null === updatePayload + ? ((newProps.childLanes = 0), + (newProps.lanes = type), + (newProps.child = null), + (newProps.subtreeFlags = 0), + (newProps.memoizedProps = null), + (newProps.memoizedState = null), + (newProps.updateQueue = null), + (newProps.dependencies = null), + (newProps.stateNode = null)) + : ((newProps.childLanes = updatePayload.childLanes), + (newProps.lanes = updatePayload.lanes), + (newProps.child = updatePayload.child), + (newProps.subtreeFlags = 0), + (newProps.deletions = null), + (newProps.memoizedProps = updatePayload.memoizedProps), + (newProps.memoizedState = updatePayload.memoizedState), + (newProps.updateQueue = updatePayload.updateQueue), + (newProps.type = updatePayload.type), + (type = updatePayload.dependencies), + (newProps.dependencies = + null === type + ? null + : { + lanes: type.lanes, + firstContext: type.firstContext + })), + (renderLanes = renderLanes.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2 + ); + return workInProgress.child; + } + current = current.sibling; + } + null !== type.tail && + now() > workInProgressRootRenderTargetTime && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + } + else { + if (!newProps) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.flags |= 128), + (newProps = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)), + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && + !updatePayload.alternate) + ) + return bubbleProperties(workInProgress), null; + } else + 2 * now() - type.renderingStartTime > + workInProgressRootRenderTargetTime && + 1073741824 !== renderLanes && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = type.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (type.last = updatePayload)); + } + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; + case 22: + case 23: + return ( + popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), + null !== current && + (null !== current.memoizedState) !== renderLanes && + (workInProgress.flags |= 8192), + renderLanes && 0 !== (workInProgress.mode & 1) + ? 0 !== (subtreeRenderLanes & 1073741824) && + bubbleProperties(workInProgress) + : bubbleProperties(workInProgress), + null + ); + case 24: + return null; + case 25: + return null; + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} function unwindWork(current, workInProgress) { popTreeContext(workInProgress); switch (workInProgress.tag) { @@ -5624,13 +5834,20 @@ function unwindWork(current, workInProgress) { case 5: return popHostContext(workInProgress), null; case 13: - return ( - pop(suspenseStackCursor), - (current = workInProgress.flags), - current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), workInProgress) - : null - ); + pop(suspenseStackCursor); + current = workInProgress.memoizedState; + if ( + null !== current && + null !== current.dehydrated && + null === workInProgress.alternate + ) + throw Error( + "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." + ); + current = workInProgress.flags; + return current & 65536 + ? ((workInProgress.flags = (current & -65537) | 128), workInProgress) + : null; case 19: return pop(suspenseStackCursor), null; case 4: @@ -5754,8 +5971,8 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create$77 = effect.create; - effect.destroy = create$77(); + var create$73 = effect.create; + effect.destroy = create$73(); } effect = effect.next; } while (effect !== finishedWork); @@ -5777,41 +5994,113 @@ function detachFiberAfterEffects(fiber) { fiber.stateNode = null; fiber.updateQueue = null; } -function commitWork(current, finishedWork) { - switch (finishedWork.tag) { +function recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + parent +) { + for (parent = parent.child; null !== parent; ) + commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, parent), + (parent = parent.sibling); +} +function commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + deletedFiber +) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) + try { + injectedHook.onCommitFiberUnmount(rendererID, deletedFiber); + } catch (err) {} + switch (deletedFiber.tag) { + case 5: + safelyDetachRef(deletedFiber, nearestMountedAncestor); + case 6: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 18: + break; + case 4: + createChildNodeSet(deletedFiber.stateNode.containerInfo); + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; case 0: case 11: case 14: case 15: - commitHookEffectListUnmount(3, finishedWork, finishedWork.return); - commitHookEffectListMount(3, finishedWork); - commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - return; - case 12: - return; - case 13: - attachSuspenseRetryListeners(finishedWork); - return; - case 19: - attachSuspenseRetryListeners(finishedWork); - return; + var updateQueue = deletedFiber.updateQueue; + if ( + null !== updateQueue && + ((updateQueue = updateQueue.lastEffect), null !== updateQueue) + ) { + var effect = (updateQueue = updateQueue.next); + do { + var _effect = effect, + destroy = _effect.destroy; + _effect = _effect.tag; + void 0 !== destroy && + (0 !== (_effect & 2) + ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) + : 0 !== (_effect & 4) && + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + )); + effect = effect.next; + } while (effect !== updateQueue); + } + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 1: + safelyDetachRef(deletedFiber, nearestMountedAncestor); + updateQueue = deletedFiber.stateNode; + if ("function" === typeof updateQueue.componentWillUnmount) + try { + (updateQueue.props = deletedFiber.memoizedProps), + (updateQueue.state = deletedFiber.memoizedState), + updateQueue.componentWillUnmount(); + } catch (error) { + captureCommitPhaseError(deletedFiber, nearestMountedAncestor, error); + } + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 21: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; case 22: - case 23: - return; - } - a: { - switch (finishedWork.tag) { - case 1: - case 5: - case 6: - break a; - case 3: - case 4: - break a; - } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + default: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5828,146 +6117,106 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function commitMutationEffects(root, firstChild) { - for (nextEffect = firstChild; null !== nextEffect; ) { - root = nextEffect; - firstChild = root.deletions; - if (null !== firstChild) - for (var i = 0; i < firstChild.length; i++) { - var childToDelete = firstChild[i]; +function recursivelyTraverseMutationEffects(root, parentFiber) { + var deletions = parentFiber.deletions; + if (null !== deletions) + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; + try { + commitDeletionEffectsOnFiber(root, parentFiber, childToDelete); + var alternate = childToDelete.alternate; + null !== alternate && (alternate.return = null); + childToDelete.return = null; + } catch (error) { + captureCommitPhaseError(childToDelete, parentFiber, error); + } + } + if (parentFiber.subtreeFlags & 12854) + for (parentFiber = parentFiber.child; null !== parentFiber; ) + commitMutationEffectsOnFiber(parentFiber, root), + (parentFiber = parentFiber.sibling); +} +function commitMutationEffectsOnFiber(finishedWork, root) { + var current = finishedWork.alternate, + flags = finishedWork.flags; + switch (finishedWork.tag) { + case 0: + case 11: + case 14: + case 15: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & 4) { try { - a: for (var node = childToDelete; ; ) { - var current = node; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, current); - } catch (err) {} - switch (current.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = current.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next, - effect = firstEffect; - do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; - void 0 !== destroy && - (0 !== (tag & 2) - ? safelyCallDestroy(current, root, destroy) - : 0 !== (tag & 4) && - safelyCallDestroy(current, root, destroy)); - effect = effect.next; - } while (effect !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(current, root); - var instance = current.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (effect = current), - (_effect = instance), - (_effect.props = effect.memoizedProps), - (_effect.state = effect.memoizedState), - _effect.componentWillUnmount(); - } catch (error) { - captureCommitPhaseError(current, root, error); - } - break; - case 5: - safelyDetachRef(current, root); - break; - case 4: - createChildNodeSet(current.stateNode.containerInfo); - } - if (null !== node.child) - (node.child.return = node), (node = node.child); - else { - if (node === childToDelete) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === childToDelete) - break a; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } - } - var alternate = childToDelete.alternate; - null !== alternate && (alternate.return = null); - childToDelete.return = null; + commitHookEffectListUnmount(3, finishedWork, finishedWork.return), + commitHookEffectListMount(3, finishedWork); } catch (error) { - captureCommitPhaseError(childToDelete, root, error); + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + try { + commitHookEffectListUnmount(5, finishedWork, finishedWork.return); + } catch (error$77) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$77); } } - firstChild = root.child; - if (0 !== (root.subtreeFlags & 12854) && null !== firstChild) - (firstChild.return = root), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - var flags = root.flags; - if (flags & 512) { - var current$jscomp$0 = root.alternate; - if (null !== current$jscomp$0) { - var currentRef = current$jscomp$0.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - if (flags & 8192) - switch (root.tag) { - case 13: - if (null !== root.memoizedState) { - var current$81 = root.alternate; - if (null === current$81 || null === current$81.memoizedState) - globalMostRecentFallbackTime = now(); - } - } - switch (flags & 4102) { - case 2: - root.flags &= -3; - break; - case 6: - root.flags &= -3; - commitWork(root.alternate, root); - break; - case 4096: - root.flags &= -4097; - break; - case 4100: - root.flags &= -4097; - commitWork(root.alternate, root); - break; - case 4: - commitWork(root.alternate, root); - } - } catch (error) { - captureCommitPhaseError(root, root.return, error); - } - firstChild = root.sibling; - if (null !== firstChild) { - firstChild.return = root.return; - nextEffect = firstChild; - break; - } - nextEffect = root.return; - } + break; + case 1: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 512 && + null !== current && + safelyDetachRef(current, current.return); + break; + case 5: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 512 && + null !== current && + safelyDetachRef(current, current.return); + break; + case 6: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 3: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 4: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 13: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + root = finishedWork.child; + root.flags & 8192 && + null !== root.memoizedState && + (null === root.alternate || null === root.alternate.memoizedState) && + (globalMostRecentFallbackTime = now()); + flags & 4 && attachSuspenseRetryListeners(finishedWork); + break; + case 22: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 19: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 4 && attachSuspenseRetryListeners(finishedWork); + break; + case 21: + break; + default: + recursivelyTraverseMutationEffects(root, finishedWork), + commitReconciliationEffects(finishedWork); } } +function commitReconciliationEffects(finishedWork) { + var flags = finishedWork.flags; + flags & 2 && (finishedWork.flags &= -3); + flags & 4096 && (finishedWork.flags &= -4097); +} function commitLayoutEffects(finishedWork) { for (nextEffect = finishedWork; null !== nextEffect; ) { var fiber = nextEffect, @@ -6010,8 +6259,8 @@ function commitLayoutEffects(finishedWork) { commitUpdateQueue(firstChild, updateQueue, instance); break; case 3: - var updateQueue$78 = firstChild.updateQueue; - if (null !== updateQueue$78) { + var updateQueue$74 = firstChild.updateQueue; + if (null !== updateQueue$74) { current = null; if (null !== firstChild.child) switch (firstChild.child.tag) { @@ -6021,7 +6270,7 @@ function commitLayoutEffects(finishedWork) { case 1: current = firstChild.child.stateNode; } - commitUpdateQueue(firstChild, updateQueue$78, current); + commitUpdateQueue(firstChild, updateQueue$74, current); } break; case 5: @@ -6043,6 +6292,7 @@ function commitLayoutEffects(finishedWork) { case 21: case 22: case 23: + case 25: break; default: throw Error( @@ -6103,6 +6353,7 @@ var ceil = Math.ceil, workInProgressRootRecoverableErrors = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, + workInProgressTransitions = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -6127,10 +6378,7 @@ function requestUpdateLane(fiber) { if (null !== ReactCurrentBatchConfig.transition) return ( 0 === currentEventTransitionLane && - ((fiber = nextTransitionLane), - (nextTransitionLane <<= 1), - 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64), - (currentEventTransitionLane = fiber)), + (currentEventTransitionLane = claimNextTransitionLane()), currentEventTransitionLane ); fiber = currentUpdatePriority; @@ -6186,6 +6434,13 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { (sourceFiber = sourceFiber.return); return 3 === alternate.tag ? alternate.stateNode : null; } +function isInterleavedUpdate(fiber) { + return ( + (null !== workInProgressRoot || null !== interleavedQueues) && + 0 !== (fiber.mode & 1) && + 0 === (executionContext & 2) + ); +} function ensureRootIsScheduled(root, currentTime) { for ( var existingCallbackNode = root.callbackNode, @@ -6281,7 +6536,8 @@ function performConcurrentWorkOnRoot(root, didTimeout) { workInProgressRoot !== root || workInProgressRootRenderLanes !== didTimeout ) - (workInProgressRootRenderTargetTime = now() + 500), + (workInProgressTransitions = null), + (workInProgressRootRenderTargetTime = now() + 500), prepareFreshStack(root, didTimeout); do try { @@ -6338,7 +6594,11 @@ function performConcurrentWorkOnRoot(root, didTimeout) { case 1: throw Error("Root did not complete. This is a bug in React."); case 2: - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 3: markRootSuspended$1(root, lanes); @@ -6355,12 +6615,21 @@ function performConcurrentWorkOnRoot(root, didTimeout) { break; } root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), didTimeout ); break; } - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 4: markRootSuspended$1(root, lanes); @@ -6391,15 +6660,28 @@ function performConcurrentWorkOnRoot(root, didTimeout) { : 1960 * ceil(lanes / 1960)) - lanes; if (10 < lanes) { root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), lanes ); break; } - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 5: - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; default: throw Error("Unknown root exit status."); @@ -6419,15 +6701,17 @@ function recoverFromConcurrentError(root, errorRetryLanes) { 2 !== root && ((errorRetryLanes = workInProgressRootRecoverableErrors), (workInProgressRootRecoverableErrors = errorsFromFirstAttempt), - null !== errorRetryLanes && - (null === workInProgressRootRecoverableErrors - ? (workInProgressRootRecoverableErrors = errorRetryLanes) - : workInProgressRootRecoverableErrors.push.apply( - workInProgressRootRecoverableErrors, - errorRetryLanes - ))); + null !== errorRetryLanes && queueRecoverableErrors(errorRetryLanes)); return root; } +function queueRecoverableErrors(errors) { + null === workInProgressRootRecoverableErrors + ? (workInProgressRootRecoverableErrors = errors) + : workInProgressRootRecoverableErrors.push.apply( + workInProgressRootRecoverableErrors, + errors + ); +} function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { if (node.flags & 16384) { @@ -6497,7 +6781,11 @@ function performSyncWorkOnRoot(root) { throw Error("Root did not complete. This is a bug in React."); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); ensureRootIsScheduled(root, now()); return null; } @@ -6733,12 +7021,12 @@ function handleError(root$jscomp$0, thrownValue) { root.flags |= 65536; thrownValue &= -thrownValue; root.lanes |= thrownValue; - var update$31 = createClassErrorUpdate( + var update$32 = createClassErrorUpdate( root, wakeable, thrownValue ); - enqueueCapturedUpdate(root, update$31); + enqueueCapturedUpdate(root, update$32); break a; } } @@ -6777,8 +7065,8 @@ function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; var prevDispatcher = pushDispatcher(); - (workInProgressRoot === root && workInProgressRootRenderLanes === lanes) || - prepareFreshStack(root, lanes); + if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) + (workInProgressTransitions = null), prepareFreshStack(root, lanes); do try { workLoopSync(); @@ -6850,50 +7138,60 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors) { +function commitRoot(root, recoverableErrors, transitions) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$2.transition; try { (ReactCurrentBatchConfig$2.transition = null), (currentUpdatePriority = 1), - commitRootImpl(root, recoverableErrors, previousUpdateLanePriority); + commitRootImpl( + root, + recoverableErrors, + transitions, + previousUpdateLanePriority + ); } finally { (ReactCurrentBatchConfig$2.transition = prevTransition), (currentUpdatePriority = previousUpdateLanePriority); } return null; } -function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { +function commitRootImpl( + root, + recoverableErrors, + transitions, + renderPriorityLevel +) { do flushPassiveEffects(); while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 6)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - if (null === finishedWork) return null; + transitions = root.finishedWork; + var lanes = root.finishedLanes; + if (null === transitions) return null; root.finishedWork = null; root.finishedLanes = 0; - if (finishedWork === root.current) + if (transitions === root.current) throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; root.callbackPriority = 0; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + var remainingLanes = transitions.lanes | transitions.childLanes; markRootFinished(root, remainingLanes); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 2064) && - 0 === (finishedWork.flags & 2064)) || + (0 === (transitions.subtreeFlags & 2064) && + 0 === (transitions.flags & 2064)) || rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), scheduleCallback$1(NormalPriority, function() { flushPassiveEffects(); return null; })); - remainingLanes = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || remainingLanes) { + remainingLanes = 0 !== (transitions.flags & 15990); + if (0 !== (transitions.subtreeFlags & 15990) || remainingLanes) { remainingLanes = ReactCurrentBatchConfig$2.transition; ReactCurrentBatchConfig$2.transition = null; var previousPriority = currentUpdatePriority; @@ -6901,30 +7199,30 @@ function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { var prevExecutionContext = executionContext; executionContext |= 4; ReactCurrentOwner$2.current = null; - commitBeforeMutationEffects(root, finishedWork); - commitMutationEffects(root, finishedWork, lanes); - root.current = finishedWork; - commitLayoutEffects(finishedWork, root, lanes); + commitBeforeMutationEffects(root, transitions); + commitMutationEffectsOnFiber(transitions, root); + root.current = transitions; + commitLayoutEffects(transitions, root, lanes); requestPaint(); executionContext = prevExecutionContext; currentUpdatePriority = previousPriority; ReactCurrentBatchConfig$2.transition = remainingLanes; - } else root.current = finishedWork; + } else root.current = transitions; rootDoesHavePassiveEffects && ((rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + onCommitRoot(transitions.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (null !== recoverableErrors) for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ + renderPriorityLevel = root.onRecoverableError, transitions = 0; + transitions < recoverableErrors.length; + transitions++ ) - renderPriorityLevel(recoverableErrors[finishedWork]); + renderPriorityLevel(recoverableErrors[transitions]); if (hasUncaughtError) throw ((hasUncaughtError = !1), (root = firstUncaughtError), @@ -7159,21 +7457,43 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { : (workInProgressRootPingedLanes |= pingedLanes)); ensureRootIsScheduled(root, wakeable); } -function resolveRetryWakeable(boundaryFiber, wakeable) { - var retryCache = boundaryFiber.stateNode; - null !== retryCache && retryCache.delete(wakeable); - wakeable = 0; - 0 === wakeable && +function retryTimedOutBoundary(boundaryFiber, retryLane) { + 0 === retryLane && (0 === (boundaryFiber.mode & 1) - ? (wakeable = 1) - : ((wakeable = nextRetryLane), + ? (retryLane = 1) + : ((retryLane = nextRetryLane), (nextRetryLane <<= 1), 0 === (nextRetryLane & 130023424) && (nextRetryLane = 4194304))); - retryCache = requestEventTime(); - boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); + var eventTime = requestEventTime(); + boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane); null !== boundaryFiber && - (markRootUpdated(boundaryFiber, wakeable, retryCache), - ensureRootIsScheduled(boundaryFiber, retryCache)); + (markRootUpdated(boundaryFiber, retryLane, eventTime), + ensureRootIsScheduled(boundaryFiber, eventTime)); +} +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState, + retryLane = 0; + null !== suspenseState && (retryLane = suspenseState.retryLane); + retryTimedOutBoundary(boundaryFiber, retryLane); +} +function resolveRetryWakeable(boundaryFiber, wakeable) { + var retryLane = 0; + switch (boundaryFiber.tag) { + case 13: + var retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + null !== suspenseState && (retryLane = suspenseState.retryLane); + break; + case 19: + retryCache = boundaryFiber.stateNode; + break; + default: + throw Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ); + } + null !== retryCache && retryCache.delete(wakeable); + retryTimedOutBoundary(boundaryFiber, retryLane); } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { @@ -7203,10 +7523,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { switch (workInProgress.tag) { case 2: var Component = workInProgress.type; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; var context = getMaskedContext( workInProgress, @@ -7260,10 +7577,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 16: Component = workInProgress.elementType; a: { - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; context = Component._init; Component = context(Component._payload); @@ -7369,7 +7683,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return ( pushHostContext(workInProgress), (Component = workInProgress.pendingProps.children), - markRef$1(current, workInProgress), + markRef(current, workInProgress), reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); @@ -7463,24 +7777,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - newValue = workInProgress.child, - null !== newValue && (newValue.return = workInProgress); - null !== newValue; + hasContext = workInProgress.child, + null !== hasContext && (hasContext.return = workInProgress); + null !== hasContext; ) { - var list = newValue.dependencies; + var list = hasContext.dependencies; if (null !== list) { - hasContext = newValue.child; + newValue = hasContext.child; for ( var dependency = list.firstContext; null !== dependency; ) { if (dependency.context === Component) { - if (1 === newValue.tag) { + if (1 === hasContext.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; - var updateQueue = newValue.updateQueue; + var updateQueue = hasContext.updateQueue; if (null !== updateQueue) { updateQueue = updateQueue.shared; var pending = updateQueue.pending; @@ -7491,11 +7805,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateQueue.pending = dependency; } } - newValue.lanes |= renderLanes; - dependency = newValue.alternate; + hasContext.lanes |= renderLanes; + dependency = hasContext.alternate; null !== dependency && (dependency.lanes |= renderLanes); scheduleContextWorkOnParentPath( - newValue.return, + hasContext.return, renderLanes, workInProgress ); @@ -7504,29 +7818,43 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } dependency = dependency.next; } - } else - hasContext = - 10 === newValue.tag - ? newValue.type === workInProgress.type - ? null - : newValue.child - : newValue.child; - if (null !== hasContext) hasContext.return = newValue; + } else if (10 === hasContext.tag) + newValue = + hasContext.type === workInProgress.type + ? null + : hasContext.child; + else if (18 === hasContext.tag) { + newValue = hasContext.return; + if (null === newValue) + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + newValue.lanes |= renderLanes; + list = newValue.alternate; + null !== list && (list.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + newValue, + renderLanes, + workInProgress + ); + newValue = hasContext.sibling; + } else newValue = hasContext.child; + if (null !== newValue) newValue.return = hasContext; else - for (hasContext = newValue; null !== hasContext; ) { - if (hasContext === workInProgress) { - hasContext = null; + for (newValue = hasContext; null !== newValue; ) { + if (newValue === workInProgress) { + newValue = null; break; } - newValue = hasContext.sibling; - if (null !== newValue) { - newValue.return = hasContext.return; - hasContext = newValue; + hasContext = newValue.sibling; + if (null !== hasContext) { + hasContext.return = newValue.return; + newValue = hasContext; break; } - hasContext = hasContext.return; + newValue = newValue.return; } - newValue = hasContext; + hasContext = newValue; } reconcileChildren( current, @@ -7577,10 +7905,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress.elementType === Component ? context : resolveDefaultProps(Component, context)), - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)), + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), (workInProgress.tag = 1), isContextProvider(Component) ? ((current = !0), pushContextProvider(workInProgress)) @@ -7920,10 +8245,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_934 = { + devToolsConfig$jscomp$inline_925 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "18.0.0-experimental-34aa5cfe0-20220329", + version: "18.2.0-next-d300cebde-20220601", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7938,11 +8263,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1178 = { - bundleType: devToolsConfig$jscomp$inline_934.bundleType, - version: devToolsConfig$jscomp$inline_934.version, - rendererPackageName: devToolsConfig$jscomp$inline_934.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_934.rendererConfig, +var internals$jscomp$inline_1171 = { + bundleType: devToolsConfig$jscomp$inline_925.bundleType, + version: devToolsConfig$jscomp$inline_925.version, + rendererPackageName: devToolsConfig$jscomp$inline_925.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_925.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7958,26 +8283,26 @@ var internals$jscomp$inline_1178 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_934.findFiberByHostInstance || + devToolsConfig$jscomp$inline_925.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.0.0-experimental-34aa5cfe0-20220329" + reconcilerVersion: "18.2.0-next-d300cebde-20220601" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1179 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1172 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1179.isDisabled && - hook$jscomp$inline_1179.supportsFiber + !hook$jscomp$inline_1172.isDisabled && + hook$jscomp$inline_1172.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1179.inject( - internals$jscomp$inline_1178 + (rendererID = hook$jscomp$inline_1172.inject( + internals$jscomp$inline_1171 )), - (injectedHook = hook$jscomp$inline_1179); + (injectedHook = hook$jscomp$inline_1172); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -8032,7 +8357,8 @@ exports.render = function(element, containerTag, callback, concurrentRoot) { element: null, isDehydrated: !1, cache: null, - transitions: null + transitions: null, + pendingSuspenseBoundaries: null }), initializeUpdateQueue(root), (root = concurrentRoot), diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.js b/Libraries/Renderer/implementations/ReactFabric-profiling.js index dee0ec43622..d8823b6d8e7 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactFabric-profiling * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<> */ @@ -1028,7 +1028,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_223 = { +var injectedNamesToPlugins$jscomp$inline_229 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1074,33 +1074,33 @@ var injectedNamesToPlugins$jscomp$inline_223 = { } } }, - isOrderingDirty$jscomp$inline_224 = !1, - pluginName$jscomp$inline_225; -for (pluginName$jscomp$inline_225 in injectedNamesToPlugins$jscomp$inline_223) + isOrderingDirty$jscomp$inline_230 = !1, + pluginName$jscomp$inline_231; +for (pluginName$jscomp$inline_231 in injectedNamesToPlugins$jscomp$inline_229) if ( - injectedNamesToPlugins$jscomp$inline_223.hasOwnProperty( - pluginName$jscomp$inline_225 + injectedNamesToPlugins$jscomp$inline_229.hasOwnProperty( + pluginName$jscomp$inline_231 ) ) { - var pluginModule$jscomp$inline_226 = - injectedNamesToPlugins$jscomp$inline_223[pluginName$jscomp$inline_225]; + var pluginModule$jscomp$inline_232 = + injectedNamesToPlugins$jscomp$inline_229[pluginName$jscomp$inline_231]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_225) || - namesToPlugins[pluginName$jscomp$inline_225] !== - pluginModule$jscomp$inline_226 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_231) || + namesToPlugins[pluginName$jscomp$inline_231] !== + pluginModule$jscomp$inline_232 ) { - if (namesToPlugins[pluginName$jscomp$inline_225]) + if (namesToPlugins[pluginName$jscomp$inline_231]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_225 + "`.") + (pluginName$jscomp$inline_231 + "`.") ); namesToPlugins[ - pluginName$jscomp$inline_225 - ] = pluginModule$jscomp$inline_226; - isOrderingDirty$jscomp$inline_224 = !0; + pluginName$jscomp$inline_231 + ] = pluginModule$jscomp$inline_232; + isOrderingDirty$jscomp$inline_230 = !0; } } -isOrderingDirty$jscomp$inline_224 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_230 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -1870,6 +1870,12 @@ function getLanesToRetrySynchronouslyOnError(root) { root = root.pendingLanes & -1073741825; return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; } +function claimNextTransitionLane() { + var lane = nextTransitionLane; + nextTransitionLane <<= 1; + 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64); + return lane; +} function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; @@ -2248,7 +2254,28 @@ function flushSyncCallbacks() { } return null; } -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +var forkStack = [], + forkStackIndex = 0, + treeForkProvider = null, + idStack = [], + idStackIndex = 0, + treeContextProvider = null; +function popTreeContext(workInProgress) { + for (; workInProgress === treeForkProvider; ) + (treeForkProvider = forkStack[--forkStackIndex]), + (forkStack[forkStackIndex] = null), + --forkStackIndex, + (forkStack[forkStackIndex] = null); + for (; workInProgress === treeContextProvider; ) + (treeContextProvider = idStack[--idStackIndex]), + (idStack[idStackIndex] = null), + --idStackIndex, + (idStack[idStackIndex] = null), + --idStackIndex, + (idStack[idStackIndex] = null); +} +var hydrationErrors = null, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function shallowEqual(objA, objB) { if (objectIs(objA, objB)) return !0; if ( @@ -2393,9 +2420,7 @@ function enqueueUpdate(fiber, update) { var updateQueue = fiber.updateQueue; null !== updateQueue && ((updateQueue = updateQueue.shared), - null !== workInProgressRoot && - 0 !== (fiber.mode & 1) && - 0 === (executionContext & 2) + isInterleavedUpdate(fiber) ? ((fiber = updateQueue.interleaved), null === fiber ? ((update.next = update), @@ -2763,26 +2788,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var forkStack = [], - forkStackIndex = 0, - treeForkProvider = null, - idStack = [], - idStackIndex = 0, - treeContextProvider = null; -function popTreeContext(workInProgress) { - for (; workInProgress === treeForkProvider; ) - (treeForkProvider = forkStack[--forkStackIndex]), - (forkStack[forkStackIndex] = null), - --forkStackIndex, - (forkStack[forkStackIndex] = null); - for (; workInProgress === treeContextProvider; ) - (treeContextProvider = idStack[--idStackIndex]), - (idStack[idStackIndex] = null), - --idStackIndex, - (idStack[idStackIndex] = null), - --idStackIndex, - (idStack[idStackIndex] = null); -} function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2845,6 +2850,10 @@ function throwOnInvalidObjectType(returnFiber, newChild) { "). If you meant to render a collection of children, use an array instead." ); } +function resolveLazy(lazyType) { + var init = lazyType._init; + return init(lazyType._payload); +} function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { @@ -2917,7 +2926,14 @@ function ChildReconciler(shouldTrackSideEffects) { lanes, element.key ); - if (null !== current && current.elementType === elementType) + if ( + null !== current && + (current.elementType === elementType || + ("object" === typeof elementType && + null !== elementType && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === current.type)) + ) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -3008,6 +3024,9 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild.return = returnFiber), newChild ); + case REACT_LAZY_TYPE: + var init = newChild._init; + return createChild(returnFiber, init(newChild._payload), lanes); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -3043,6 +3062,11 @@ function ChildReconciler(shouldTrackSideEffects) { return newChild.key === key ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; + case REACT_LAZY_TYPE: + return ( + (key = newChild._init), + updateSlot(returnFiber, oldFiber, key(newChild._payload), lanes) + ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key @@ -3085,6 +3109,15 @@ function ChildReconciler(shouldTrackSideEffects) { ) || null), updatePortal(returnFiber, existingChildren, newChild, lanes) ); + case REACT_LAZY_TYPE: + var init = newChild._init; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + init(newChild._payload), + lanes + ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -3262,7 +3295,12 @@ function ChildReconciler(shouldTrackSideEffects) { }); return iteratorFn; } - return function(returnFiber, currentFirstChild, newChild, lanes) { + function reconcileChildFibers( + returnFiber, + currentFirstChild, + newChild, + lanes + ) { "object" === typeof newChild && null !== newChild && newChild.type === REACT_FRAGMENT_TYPE && @@ -3290,7 +3328,13 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; break a; } - } else if (child.elementType === key) { + } else if ( + child.elementType === key || + ("object" === typeof key && + null !== key && + key.$$typeof === REACT_LAZY_TYPE && + resolveLazy(key) === child.type) + ) { deleteRemainingChildren(returnFiber, child.sibling); currentFirstChild = useFiber(child, newChild.props); currentFirstChild.ref = coerceRef( @@ -3371,6 +3415,16 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; } return placeSingleChild(returnFiber); + case REACT_LAZY_TYPE: + return ( + (child = newChild._init), + reconcileChildFibers( + returnFiber, + currentFirstChild, + child(newChild._payload), + lanes + ) + ); } if (isArrayImpl(newChild)) return reconcileChildrenArray( @@ -3406,7 +3460,8 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber)) : deleteRemainingChildren(returnFiber, currentFirstChild); - }; + } + return reconcileChildFibers; } var reconcileChildFibers = ChildReconciler(!0), mountChildFibers = ChildReconciler(!1), @@ -3893,6 +3948,19 @@ function updateMemo(nextCreate, deps) { hook.memoizedState = [nextCreate, deps]; return nextCreate; } +function updateDeferredValueImpl(hook, prevValue, value) { + if (0 === (renderLanes & 21)) + return ( + hook.baseState && ((hook.baseState = !1), (didReceiveUpdate = !0)), + (hook.memoizedState = value) + ); + objectIs(value, prevValue) || + ((value = claimNextTransitionLane()), + (currentlyRenderingFiber$1.lanes |= value), + (workInProgressRootSkippedLanes |= value), + (hook.baseState = !0)); + return prevValue; +} function startTransition(setPending, callback) { var previousPriority = currentUpdatePriority; currentUpdatePriority = @@ -3974,9 +4042,7 @@ function enqueueRenderPhaseUpdate(queue, update) { queue.pending = update; } function enqueueUpdate$1(fiber, queue, update) { - null !== workInProgressRoot && - 0 !== (fiber.mode & 1) && - 0 === (executionContext & 2) + isInterleavedUpdate(fiber) ? ((fiber = queue.interleaved), null === fiber ? ((update.next = update), @@ -4081,29 +4147,14 @@ var ContextOnlyDispatcher = { useState: mountState, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _mountState = mountState(value), - prevValue = _mountState[0], - setValue = _mountState[1]; - mountEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + return (mountWorkInProgressHook().memoizedState = value); }, useTransition: function() { - var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = startTransition.bind(null, _mountState2[1]); - mountWorkInProgressHook().memoizedState = _mountState2; - return [isPending, _mountState2]; + var _mountState = mountState(!1), + isPending = _mountState[0]; + _mountState = startTransition.bind(null, _mountState[1]); + mountWorkInProgressHook().memoizedState = _mountState; + return [isPending, _mountState]; }, useMutableSource: function() {}, useSyncExternalStore: function(subscribe, getSnapshot) { @@ -4157,22 +4208,8 @@ var ContextOnlyDispatcher = { }, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _updateState = updateReducer(basicStateReducer), - prevValue = _updateState[0], - setValue = _updateState[1]; - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + return updateDeferredValueImpl(hook, currentHook.memoizedState, value); }, useTransition: function() { var isPending = updateReducer(basicStateReducer)[0], @@ -4200,22 +4237,10 @@ var ContextOnlyDispatcher = { }, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + return null === currentHook + ? (hook.memoizedState = value) + : updateDeferredValueImpl(hook, currentHook.memoizedState, value); }, useTransition: function() { var isPending = rerenderReducer(basicStateReducer)[0], @@ -4377,553 +4402,6 @@ function attachPingListener(root, wakeable, lanes) { isDevToolsPresent && restorePendingUpdaters(root, lanes), wakeable.then(pingCache, pingCache)); } -function hadNoMutationsEffects(current, completedWork) { - if (null !== current && current.child === completedWork.child) return !0; - if (0 !== (completedWork.flags & 16)) return !1; - for (current = completedWork.child; null !== current; ) { - if (0 !== (current.flags & 12854) || 0 !== (current.subtreeFlags & 12854)) - return !1; - current = current.sibling; - } - return !0; -} -var appendAllChildren, updateHostContainer, updateHostComponent, updateHostText; -appendAllChildren = function( - parent, - workInProgress, - needsVisibilityToggle, - isHidden -) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag) { - var instance = node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNode(parent.node, instance.node); - } else if (6 === node.tag) { - instance = node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNode(parent.node, instance.node); - } else if (4 !== node.tag) - if (22 === node.tag && null !== node.memoizedState) - (instance = node.child), - null !== instance && (instance.return = node), - appendAllChildren(parent, node, !0, !0); - else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -}; -function appendAllChildrenToContainer( - containerChildSet, - workInProgress, - needsVisibilityToggle, - isHidden -) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag) { - var instance = node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (6 === node.tag) { - instance = node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (4 !== node.tag) - if (22 === node.tag && null !== node.memoizedState) - (instance = node.child), - null !== instance && (instance.return = node), - appendAllChildrenToContainer(containerChildSet, node, !0, !0); - else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -} -updateHostContainer = function(current, workInProgress) { - var portalOrRoot = workInProgress.stateNode; - if (!hadNoMutationsEffects(current, workInProgress)) { - current = portalOrRoot.containerInfo; - var newChildSet = createChildNodeSet(current); - appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); - portalOrRoot.pendingChildren = newChildSet; - workInProgress.flags |= 4; - completeRoot(current, newChildSet); - } -}; -updateHostComponent = function(current, workInProgress, type, newProps) { - type = current.stateNode; - var oldProps = current.memoizedProps; - if ( - (current = hadNoMutationsEffects(current, workInProgress)) && - oldProps === newProps - ) - workInProgress.stateNode = type; - else { - var recyclableInstance = workInProgress.stateNode; - requiredContext(contextStackCursor$1.current); - var updatePayload = null; - oldProps !== newProps && - ((oldProps = diffProperties( - null, - oldProps, - newProps, - recyclableInstance.canonical.viewConfig.validAttributes - )), - (recyclableInstance.canonical.currentProps = newProps), - (updatePayload = oldProps)); - current && null === updatePayload - ? (workInProgress.stateNode = type) - : ((newProps = updatePayload), - (oldProps = type.node), - (type = { - node: current - ? null !== newProps - ? cloneNodeWithNewProps(oldProps, newProps) - : cloneNode(oldProps) - : null !== newProps - ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) - : cloneNodeWithNewChildren(oldProps), - canonical: type.canonical - }), - (workInProgress.stateNode = type), - current - ? (workInProgress.flags |= 4) - : appendAllChildren(type, workInProgress, !1, !1)); - } -}; -updateHostText = function(current, workInProgress, oldText, newText) { - oldText !== newText - ? ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.flags |= 4)) - : (workInProgress.stateNode = current.stateNode); -}; -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var lastTailNode$37 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$37 = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === lastTailNode$37 - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (lastTailNode$37.sibling = null); - } -} -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - if (0 !== (completedWork.mode & 2)) { - for ( - var treeBaseDuration$39 = completedWork.selfBaseDuration, - child$40 = completedWork.child; - null !== child$40; - - ) - (newChildLanes |= child$40.lanes | child$40.childLanes), - (subtreeFlags |= child$40.subtreeFlags & 14680064), - (subtreeFlags |= child$40.flags & 14680064), - (treeBaseDuration$39 += child$40.treeBaseDuration), - (child$40 = child$40.sibling); - completedWork.treeBaseDuration = treeBaseDuration$39; - } else - for ( - treeBaseDuration$39 = completedWork.child; - null !== treeBaseDuration$39; - - ) - (newChildLanes |= - treeBaseDuration$39.lanes | treeBaseDuration$39.childLanes), - (subtreeFlags |= treeBaseDuration$39.subtreeFlags & 14680064), - (subtreeFlags |= treeBaseDuration$39.flags & 14680064), - (treeBaseDuration$39.return = completedWork), - (treeBaseDuration$39 = treeBaseDuration$39.sibling); - else if (0 !== (completedWork.mode & 2)) { - treeBaseDuration$39 = completedWork.actualDuration; - child$40 = completedWork.selfBaseDuration; - for (var child = completedWork.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (subtreeFlags |= child.subtreeFlags), - (subtreeFlags |= child.flags), - (treeBaseDuration$39 += child.actualDuration), - (child$40 += child.treeBaseDuration), - (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$39; - completedWork.treeBaseDuration = child$40; - } else - for ( - treeBaseDuration$39 = completedWork.child; - null !== treeBaseDuration$39; - - ) - (newChildLanes |= - treeBaseDuration$39.lanes | treeBaseDuration$39.childLanes), - (subtreeFlags |= treeBaseDuration$39.subtreeFlags), - (subtreeFlags |= treeBaseDuration$39.flags), - (treeBaseDuration$39.return = completedWork), - (treeBaseDuration$39 = treeBaseDuration$39.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; - popTreeContext(workInProgress); - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); - case 3: - return ( - (newProps = workInProgress.stateNode), - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - resetWorkInProgressVersions(), - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)), - (null !== current && null !== current.child) || - null === current || - (current.memoizedState.isDehydrated && - 0 === (workInProgress.flags & 256)) || - (workInProgress.flags |= 1024), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 5: - popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent( - current, - workInProgress, - type, - newProps, - renderLanes - ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 512); - else { - if (!newProps) { - if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - bubbleProperties(workInProgress); - return null; - } - requiredContext(contextStackCursor$1.current); - current = nextReactTag; - nextReactTag += 2; - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - renderLanes = createNode( - current, - type.uiViewClassName, - renderLanes, - updatePayload, - workInProgress - ); - current = new ReactFabricHostComponent( - current, - type, - newProps, - workInProgress - ); - current = { node: renderLanes, canonical: current }; - appendAllChildren(current, workInProgress, !1, !1); - workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 512); - } - bubbleProperties(workInProgress); - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - renderLanes = requiredContext(contextStackCursor$1.current); - workInProgress.stateNode = createTextInstance( - newProps, - current, - renderLanes, - workInProgress - ); - } - bubbleProperties(workInProgress); - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) - return ( - (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress - ); - newProps = null !== newProps; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - newProps && - !renderLanes && - ((workInProgress.child.flags |= 8192), - 0 !== (workInProgress.mode & 1) && - (null === current || 0 !== (suspenseStackCursor.current & 1) - ? 0 === workInProgressRootExitStatus && - (workInProgressRootExitStatus = 3) - : renderDidSuspendDelayIfPossible())); - null !== workInProgress.updateQueue && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 2) && - newProps && - ((current = workInProgress.child), - null !== current && - (workInProgress.treeBaseDuration -= current.treeBaseDuration)); - return null; - case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); - case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); - case 19: - pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; - if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); - else { - if ( - 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (updatePayload = current), - (renderLanes.flags &= 14680066), - (type = renderLanes.alternate), - null === type - ? ((renderLanes.childLanes = 0), - (renderLanes.lanes = updatePayload), - (renderLanes.child = null), - (renderLanes.subtreeFlags = 0), - (renderLanes.memoizedProps = null), - (renderLanes.memoizedState = null), - (renderLanes.updateQueue = null), - (renderLanes.dependencies = null), - (renderLanes.stateNode = null), - (renderLanes.selfBaseDuration = 0), - (renderLanes.treeBaseDuration = 0)) - : ((renderLanes.childLanes = type.childLanes), - (renderLanes.lanes = type.lanes), - (renderLanes.child = type.child), - (renderLanes.subtreeFlags = 0), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = type.memoizedProps), - (renderLanes.memoizedState = type.memoizedState), - (renderLanes.updateQueue = type.updateQueue), - (renderLanes.type = type.type), - (updatePayload = type.dependencies), - (renderLanes.dependencies = - null === updatePayload - ? null - : { - lanes: updatePayload.lanes, - firstContext: updatePayload.firstContext - }), - (renderLanes.selfBaseDuration = type.selfBaseDuration), - (renderLanes.treeBaseDuration = type.treeBaseDuration)), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== type.tail && - now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && - !updatePayload.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now() - type.renderingStartTime > - workInProgressRootRenderTargetTime && - 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - type.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (type.last = updatePayload)); - } - if (null !== type.tail) - return ( - (workInProgress = type.tail), - (type.rendering = workInProgress), - (type.tail = workInProgress.sibling), - (type.renderingStartTime = now()), - (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), - workInProgress - ); - bubbleProperties(workInProgress); - return null; - case 22: - case 23: - return ( - popRenderLanes(), - (newProps = null !== workInProgress.memoizedState), - null !== current && - (null !== current.memoizedState) !== newProps && - (workInProgress.flags |= 8192), - newProps && 0 !== (workInProgress.mode & 1) - ? 0 !== (subtreeRenderLanes & 1073741824) && - bubbleProperties(workInProgress) - : bubbleProperties(workInProgress), - null - ); - case 24: - return null; - case 25: - return null; - } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); -} var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { @@ -5026,18 +4504,24 @@ function updateSimpleMemoComponent( nextProps, renderLanes ) { - if ( - null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes))) - 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); - else - return ( - (workInProgress.lanes = current.lanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); + if (null !== current) { + var prevProps = current.memoizedProps; + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref + ) + if ( + ((didReceiveUpdate = !1), + (workInProgress.pendingProps = nextProps = prevProps), + 0 !== (current.lanes & renderLanes)) + ) + 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); + else + return ( + (workInProgress.lanes = current.lanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + } return updateFunctionComponent( current, workInProgress, @@ -5052,7 +4536,11 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { prevState = null !== current ? current.memoizedState : null; if ("hidden" === nextProps.mode) if (0 === (workInProgress.mode & 1)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + (workInProgress.memoizedState = { + baseLanes: 0, + cachePool: null, + transitions: null + }), push(subtreeRenderLanesCursor, subtreeRenderLanes), (subtreeRenderLanes |= renderLanes); else { @@ -5065,14 +4553,19 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { (workInProgress.lanes = workInProgress.childLanes = 1073741824), (workInProgress.memoizedState = { baseLanes: current, - cachePool: null + cachePool: null, + transitions: null }), (workInProgress.updateQueue = null), push(subtreeRenderLanesCursor, subtreeRenderLanes), (subtreeRenderLanes |= current), null ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + workInProgress.memoizedState = { + baseLanes: 0, + cachePool: null, + transitions: null + }; nextProps = null !== prevState ? prevState.baseLanes : renderLanes; push(subtreeRenderLanesCursor, subtreeRenderLanes); subtreeRenderLanes |= nextProps; @@ -5087,7 +4580,7 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef$1(current, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( (null === current && null !== ref) || @@ -5139,10 +4632,7 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderLanes); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)), + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), constructClassInstance(workInProgress, Component, nextProps), mountClassInstance(workInProgress, Component, nextProps, renderLanes), (nextProps = !0); @@ -5336,7 +4826,7 @@ function finishClassComponent( hasContext, renderLanes ) { - markRef$1(current, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( @@ -5386,14 +4876,15 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, treeContext: null, retryLane: 0 }; function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: null }; + return { baseLanes: renderLanes, cachePool: null, transitions: null }; } function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, + didSuspend = 0 !== (workInProgress.flags & 128), JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || + (JSCompiler_temp = didSuspend) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 @@ -5403,177 +4894,307 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext |= 1; push(suspenseStackCursor, suspenseContext & 1); if (null === current) { - suspenseContext = nextProps.children; - current = nextProps.fallback; - if (showFallback) + current = workInProgress.memoizedState; + if (null !== current && null !== current.dehydrated) return ( - (showFallback = workInProgress.mode), - (nextProps = workInProgress.child), - (suspenseContext = { mode: "hidden", children: suspenseContext }), - 0 === (showFallback & 1) && null !== nextProps - ? ((nextProps.childLanes = 0), - (nextProps.pendingProps = suspenseContext), + 0 === (workInProgress.mode & 1) + ? (workInProgress.lanes = 1) + : shim$1() + ? (workInProgress.lanes = 8) + : (workInProgress.lanes = 1073741824), + null + ); + didSuspend = nextProps.children; + current = nextProps.fallback; + return showFallback + ? ((nextProps = workInProgress.mode), + (showFallback = workInProgress.child), + (didSuspend = { mode: "hidden", children: didSuspend }), + 0 === (nextProps & 1) && null !== showFallback + ? ((showFallback.childLanes = 0), + (showFallback.pendingProps = didSuspend), workInProgress.mode & 2 && - ((nextProps.actualDuration = 0), - (nextProps.actualStartTime = -1), - (nextProps.selfBaseDuration = 0), - (nextProps.treeBaseDuration = 0))) - : (nextProps = createFiberFromOffscreen( - suspenseContext, - showFallback, + ((showFallback.actualDuration = 0), + (showFallback.actualStartTime = -1), + (showFallback.selfBaseDuration = 0), + (showFallback.treeBaseDuration = 0))) + : (showFallback = createFiberFromOffscreen( + didSuspend, + nextProps, 0, null )), (current = createFiberFromFragment( current, - showFallback, + nextProps, renderLanes, null )), - (nextProps.return = workInProgress), + (showFallback.return = workInProgress), (current.return = workInProgress), - (nextProps.sibling = current), - (workInProgress.child = nextProps), + (showFallback.sibling = current), + (workInProgress.child = showFallback), (workInProgress.child.memoizedState = mountSuspenseOffscreenState( renderLanes )), (workInProgress.memoizedState = SUSPENDED_MARKER), - current - ); - renderLanes = createFiberFromOffscreen( - { mode: "visible", children: suspenseContext }, - workInProgress.mode, - 0, - null - ); - renderLanes.return = workInProgress; - return (workInProgress.child = renderLanes); + current) + : mountSuspensePrimaryChildren(workInProgress, didSuspend); } - if (null !== current.memoizedState) { - if (showFallback) - return ( - (showFallback = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (nextProps = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (nextProps.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (nextProps.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - showFallback - ); - renderLanes = updateSuspensePrimaryChildren( + suspenseContext = current.memoizedState; + if ( + null !== suspenseContext && + ((JSCompiler_temp = suspenseContext.dehydrated), null !== JSCompiler_temp) + ) + return updateDehydratedSuspenseComponent( current, workInProgress, - nextProps.children, + didSuspend, + nextProps, + JSCompiler_temp, + suspenseContext, renderLanes ); - workInProgress.memoizedState = null; - return renderLanes; + if (showFallback) { + showFallback = nextProps.fallback; + didSuspend = workInProgress.mode; + suspenseContext = current.child; + JSCompiler_temp = suspenseContext.sibling; + var primaryChildProps = { mode: "hidden", children: nextProps.children }; + 0 === (didSuspend & 1) && workInProgress.child !== suspenseContext + ? ((nextProps = workInProgress.child), + (nextProps.childLanes = 0), + (nextProps.pendingProps = primaryChildProps), + workInProgress.mode & 2 && + ((nextProps.actualDuration = 0), + (nextProps.actualStartTime = -1), + (nextProps.selfBaseDuration = suspenseContext.selfBaseDuration), + (nextProps.treeBaseDuration = suspenseContext.treeBaseDuration)), + (workInProgress.deletions = null)) + : ((nextProps = createWorkInProgress(suspenseContext, primaryChildProps)), + (nextProps.subtreeFlags = suspenseContext.subtreeFlags & 14680064)); + null !== JSCompiler_temp + ? (showFallback = createWorkInProgress(JSCompiler_temp, showFallback)) + : ((showFallback = createFiberFromFragment( + showFallback, + didSuspend, + renderLanes, + null + )), + (showFallback.flags |= 2)); + showFallback.return = workInProgress; + nextProps.return = workInProgress; + nextProps.sibling = showFallback; + workInProgress.child = nextProps; + nextProps = showFallback; + showFallback = workInProgress.child; + didSuspend = current.child.memoizedState; + didSuspend = + null === didSuspend + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: didSuspend.baseLanes | renderLanes, + cachePool: null, + transitions: didSuspend.transitions + }; + showFallback.memoizedState = didSuspend; + showFallback.childLanes = current.childLanes & ~renderLanes; + workInProgress.memoizedState = SUSPENDED_MARKER; + return nextProps; } - if (showFallback) - return ( - (showFallback = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (nextProps = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (nextProps.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (nextProps.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - showFallback - ); - renderLanes = updateSuspensePrimaryChildren( - current, - workInProgress, - nextProps.children, - renderLanes - ); - workInProgress.memoizedState = null; - return renderLanes; -} -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - primaryChildren = createWorkInProgress(currentPrimaryChildFragment, { + showFallback = current.child; + current = showFallback.sibling; + nextProps = createWorkInProgress(showFallback, { mode: "visible", - children: primaryChildren + children: nextProps.children }); - 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); - primaryChildren.return = workInProgress; - primaryChildren.sibling = null; + 0 === (workInProgress.mode & 1) && (nextProps.lanes = renderLanes); + nextProps.return = workInProgress; + nextProps.sibling = null; null !== current && ((renderLanes = workInProgress.deletions), null === renderLanes ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) : renderLanes.push(current)); + workInProgress.child = nextProps; + workInProgress.memoizedState = null; + return nextProps; +} +function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { + primaryChildren = createFiberFromOffscreen( + { mode: "visible", children: primaryChildren }, + workInProgress.mode, + 0, + null + ); + primaryChildren.return = workInProgress; return (workInProgress.child = primaryChildren); } -function updateSuspenseFallbackChildren( +function retrySuspenseComponentWithoutHydrating( current, workInProgress, - primaryChildren, - fallbackChildren, + renderLanes, + recoverableError +) { + null !== recoverableError && + (null === hydrationErrors + ? (hydrationErrors = [recoverableError]) + : hydrationErrors.push(recoverableError)); + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + current = mountSuspensePrimaryChildren( + workInProgress, + workInProgress.pendingProps.children + ); + current.flags |= 2; + workInProgress.memoizedState = null; + return current; +} +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + nextProps, + suspenseInstance, + suspenseState, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, - primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current - ? ((primaryChildren = workInProgress.child), - (primaryChildren.childLanes = 0), - (primaryChildren.pendingProps = primaryChildProps), - workInProgress.mode & 2 && - ((primaryChildren.actualDuration = 0), - (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = current.selfBaseDuration), - (primaryChildren.treeBaseDuration = current.treeBaseDuration)), - (workInProgress.deletions = null)) - : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 14680064)); - null !== currentFallbackChildFragment - ? (fallbackChildren = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - )) - : ((fallbackChildren = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, + if (didSuspend) { + if (workInProgress.flags & 256) + return ( + (workInProgress.flags &= -257), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + Error( + "There was an error while hydrating this Suspense boundary. Switched to client rendering." + ) + ) + ); + if (null !== workInProgress.memoizedState) + return ( + (workInProgress.child = current.child), + (workInProgress.flags |= 128), null - )), - (fallbackChildren.flags |= 2)); - fallbackChildren.return = workInProgress; - primaryChildren.return = workInProgress; - primaryChildren.sibling = fallbackChildren; - workInProgress.child = primaryChildren; - return fallbackChildren; + ); + suspenseState = nextProps.fallback; + didSuspend = workInProgress.mode; + nextProps = createFiberFromOffscreen( + { mode: "visible", children: nextProps.children }, + didSuspend, + 0, + null + ); + suspenseState = createFiberFromFragment( + suspenseState, + didSuspend, + renderLanes, + null + ); + suspenseState.flags |= 2; + nextProps.return = workInProgress; + suspenseState.return = workInProgress; + nextProps.sibling = suspenseState; + workInProgress.child = nextProps; + 0 !== (workInProgress.mode & 1) && + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return suspenseState; + } + if (0 === (workInProgress.mode & 1)) + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + if (shim$1()) + return ( + (suspenseState = shim$1().errorMessage), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + suspenseState + ? Error(suspenseState) + : Error( + "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." + ) + ) + ); + didSuspend = 0 !== (renderLanes & current.childLanes); + if (didReceiveUpdate || didSuspend) { + nextProps = workInProgressRoot; + if (null !== nextProps) { + switch (renderLanes & -renderLanes) { + case 4: + didSuspend = 2; + break; + case 16: + didSuspend = 8; + break; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + didSuspend = 32; + break; + case 536870912: + didSuspend = 268435456; + break; + default: + didSuspend = 0; + } + nextProps = + 0 !== (didSuspend & (nextProps.suspendedLanes | renderLanes)) + ? 0 + : didSuspend; + 0 !== nextProps && + nextProps !== suspenseState.retryLane && + ((suspenseState.retryLane = nextProps), + scheduleUpdateOnFiber(current, nextProps, -1)); + } + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + Error( + "This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition." + ) + ); + } + if (shim$1()) + return ( + (workInProgress.flags |= 128), + (workInProgress.child = current.child), + retryDehydratedSuspenseBoundary.bind(null, current), + shim$1(), + null + ); + current = mountSuspensePrimaryChildren(workInProgress, nextProps.children); + current.flags |= 4096; + return current; } function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes |= renderLanes; @@ -5692,6 +5313,13 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { } return workInProgress.child; } +function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + 0 === (workInProgress.mode & 1) && + null !== current && + ((current.alternate = null), + (workInProgress.alternate = null), + (workInProgress.flags |= 2)); +} function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; @@ -5747,7 +5375,14 @@ function attemptEarlyBailoutIfNoScheduledUpdate( context.passiveEffectDuration = 0; break; case 13: - if (null !== workInProgress.memoizedState) { + context = workInProgress.memoizedState; + if (null !== context) { + if (null !== context.dehydrated) + return ( + push(suspenseStackCursor, suspenseStackCursor.current & 1), + (workInProgress.flags |= 128), + null + ); if (0 !== (renderLanes & workInProgress.child.childLanes)) return updateSuspenseComponent(current, workInProgress, renderLanes); push(suspenseStackCursor, suspenseStackCursor.current & 1); @@ -5788,6 +5423,587 @@ function attemptEarlyBailoutIfNoScheduledUpdate( } return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } +function hadNoMutationsEffects(current, completedWork) { + if (null !== current && current.child === completedWork.child) return !0; + if (0 !== (completedWork.flags & 16)) return !1; + for (current = completedWork.child; null !== current; ) { + if (0 !== (current.flags & 12854) || 0 !== (current.subtreeFlags & 12854)) + return !1; + current = current.sibling; + } + return !0; +} +var appendAllChildren, + updateHostContainer, + updateHostComponent$1, + updateHostText$1; +appendAllChildren = function( + parent, + workInProgress, + needsVisibilityToggle, + isHidden +) { + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag) { + var instance = node.stateNode; + needsVisibilityToggle && + isHidden && + (instance = cloneHiddenInstance(instance)); + appendChildNode(parent.node, instance.node); + } else if (6 === node.tag) { + instance = node.stateNode; + if (needsVisibilityToggle && isHidden) + throw Error("Not yet implemented."); + appendChildNode(parent.node, instance.node); + } else if (4 !== node.tag) + if (22 === node.tag && null !== node.memoizedState) + (instance = node.child), + null !== instance && (instance.return = node), + appendAllChildren(parent, node, !0, !0); + else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +}; +function appendAllChildrenToContainer( + containerChildSet, + workInProgress, + needsVisibilityToggle, + isHidden +) { + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag) { + var instance = node.stateNode; + needsVisibilityToggle && + isHidden && + (instance = cloneHiddenInstance(instance)); + appendChildNodeToSet(containerChildSet, instance.node); + } else if (6 === node.tag) { + instance = node.stateNode; + if (needsVisibilityToggle && isHidden) + throw Error("Not yet implemented."); + appendChildNodeToSet(containerChildSet, instance.node); + } else if (4 !== node.tag) + if (22 === node.tag && null !== node.memoizedState) + (instance = node.child), + null !== instance && (instance.return = node), + appendAllChildrenToContainer(containerChildSet, node, !0, !0); + else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} +updateHostContainer = function(current, workInProgress) { + var portalOrRoot = workInProgress.stateNode; + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); + appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); + portalOrRoot.pendingChildren = newChildSet; + workInProgress.flags |= 4; + completeRoot(current, newChildSet); + } +}; +updateHostComponent$1 = function(current, workInProgress, type, newProps) { + type = current.stateNode; + var oldProps = current.memoizedProps; + if ( + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps + ) + workInProgress.stateNode = type; + else { + var recyclableInstance = workInProgress.stateNode; + requiredContext(contextStackCursor$1.current); + var updatePayload = null; + oldProps !== newProps && + ((oldProps = diffProperties( + null, + oldProps, + newProps, + recyclableInstance.canonical.viewConfig.validAttributes + )), + (recyclableInstance.canonical.currentProps = newProps), + (updatePayload = oldProps)); + current && null === updatePayload + ? (workInProgress.stateNode = type) + : ((newProps = updatePayload), + (oldProps = type.node), + (type = { + node: current + ? null !== newProps + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) + : null !== newProps + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), + canonical: type.canonical + }), + (workInProgress.stateNode = type), + current + ? (workInProgress.flags |= 4) + : appendAllChildren(type, workInProgress, !1, !1)); + } +}; +updateHostText$1 = function(current, workInProgress, oldText, newText) { + oldText !== newText + ? ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.flags |= 4)) + : (workInProgress.stateNode = current.stateNode); +}; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var lastTailNode$63 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === lastTailNode$63 + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (lastTailNode$63.sibling = null); + } +} +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + if (0 !== (completedWork.mode & 2)) { + for ( + var treeBaseDuration$65 = completedWork.selfBaseDuration, + child$66 = completedWork.child; + null !== child$66; + + ) + (newChildLanes |= child$66.lanes | child$66.childLanes), + (subtreeFlags |= child$66.subtreeFlags & 14680064), + (subtreeFlags |= child$66.flags & 14680064), + (treeBaseDuration$65 += child$66.treeBaseDuration), + (child$66 = child$66.sibling); + completedWork.treeBaseDuration = treeBaseDuration$65; + } else + for ( + treeBaseDuration$65 = completedWork.child; + null !== treeBaseDuration$65; + + ) + (newChildLanes |= + treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), + (subtreeFlags |= treeBaseDuration$65.subtreeFlags & 14680064), + (subtreeFlags |= treeBaseDuration$65.flags & 14680064), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + else if (0 !== (completedWork.mode & 2)) { + treeBaseDuration$65 = completedWork.actualDuration; + child$66 = completedWork.selfBaseDuration; + for (var child = completedWork.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (subtreeFlags |= child.subtreeFlags), + (subtreeFlags |= child.flags), + (treeBaseDuration$65 += child.actualDuration), + (child$66 += child.treeBaseDuration), + (child = child.sibling); + completedWork.actualDuration = treeBaseDuration$65; + completedWork.treeBaseDuration = child$66; + } else + for ( + treeBaseDuration$65 = completedWork.child; + null !== treeBaseDuration$65; + + ) + (newChildLanes |= + treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), + (subtreeFlags |= treeBaseDuration$65.subtreeFlags), + (subtreeFlags |= treeBaseDuration$65.flags), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + popTreeContext(workInProgress); + switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return bubbleProperties(workInProgress), null; + case 1: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 3: + return ( + (renderLanes = workInProgress.stateNode), + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + resetWorkInProgressVersions(), + renderLanes.pendingContext && + ((renderLanes.context = renderLanes.pendingContext), + (renderLanes.pendingContext = null)), + (null !== current && null !== current.child) || + null === current || + (current.memoizedState.isDehydrated && + 0 === (workInProgress.flags & 256)) || + ((workInProgress.flags |= 1024), + null !== hydrationErrors && + (queueRecoverableErrors(hydrationErrors), + (hydrationErrors = null))), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 5: + popHostContext(workInProgress); + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + renderLanes + ), + current.ref !== workInProgress.ref && (workInProgress.flags |= 512); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + bubbleProperties(workInProgress); + return null; + } + requiredContext(contextStackCursor$1.current); + current = nextReactTag; + nextReactTag += 2; + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + type.validAttributes + ); + renderLanes = createNode( + current, + type.uiViewClassName, + renderLanes, + updatePayload, + workInProgress + ); + current = new ReactFabricHostComponent( + current, + type, + newProps, + workInProgress + ); + current = { node: renderLanes, canonical: current }; + appendAllChildren(current, workInProgress, !1, !1); + workInProgress.stateNode = current; + null !== workInProgress.ref && (workInProgress.flags |= 512); + } + bubbleProperties(workInProgress); + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText$1( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + renderLanes = requiredContext(contextStackCursor$1.current); + workInProgress.stateNode = createTextInstance( + newProps, + current, + renderLanes, + workInProgress + ); + } + bubbleProperties(workInProgress); + return null; + case 13: + pop(suspenseStackCursor); + newProps = workInProgress.memoizedState; + if ( + null === current || + (null !== current.memoizedState && + null !== current.memoizedState.dehydrated) + ) { + if (null !== newProps && null !== newProps.dehydrated) { + if (null === current) { + throw Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ); + throw Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + 0 === (workInProgress.flags & 128) && + (workInProgress.memoizedState = null); + workInProgress.flags |= 4; + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 2) && + null !== newProps && + ((type = workInProgress.child), + null !== type && + (workInProgress.treeBaseDuration -= type.treeBaseDuration)); + type = !1; + } else + null !== hydrationErrors && + (queueRecoverableErrors(hydrationErrors), (hydrationErrors = null)), + (type = !0); + if (!type) return workInProgress.flags & 65536 ? workInProgress : null; + } + if (0 !== (workInProgress.flags & 128)) + return ( + (workInProgress.lanes = renderLanes), + 0 !== (workInProgress.mode & 2) && + transferActualDuration(workInProgress), + workInProgress + ); + renderLanes = null !== newProps; + renderLanes !== (null !== current && null !== current.memoizedState) && + renderLanes && + ((workInProgress.child.flags |= 8192), + 0 !== (workInProgress.mode & 1) && + (null === current || 0 !== (suspenseStackCursor.current & 1) + ? 0 === workInProgressRootExitStatus && + (workInProgressRootExitStatus = 3) + : renderDidSuspendDelayIfPossible())); + null !== workInProgress.updateQueue && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 2) && + renderLanes && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); + return null; + case 4: + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 10: + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor); + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; + if (null === updatePayload) + if (newProps) cutOffTailIfNeeded(type, !1); + else { + if ( + 0 !== workInProgressRootExitStatus || + (null !== current && 0 !== (current.flags & 128)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)); + workInProgress.subtreeFlags = 0; + current = renderLanes; + for (renderLanes = workInProgress.child; null !== renderLanes; ) + (newProps = renderLanes), + (updatePayload = current), + (newProps.flags &= 14680066), + (type = newProps.alternate), + null === type + ? ((newProps.childLanes = 0), + (newProps.lanes = updatePayload), + (newProps.child = null), + (newProps.subtreeFlags = 0), + (newProps.memoizedProps = null), + (newProps.memoizedState = null), + (newProps.updateQueue = null), + (newProps.dependencies = null), + (newProps.stateNode = null), + (newProps.selfBaseDuration = 0), + (newProps.treeBaseDuration = 0)) + : ((newProps.childLanes = type.childLanes), + (newProps.lanes = type.lanes), + (newProps.child = type.child), + (newProps.subtreeFlags = 0), + (newProps.deletions = null), + (newProps.memoizedProps = type.memoizedProps), + (newProps.memoizedState = type.memoizedState), + (newProps.updateQueue = type.updateQueue), + (newProps.type = type.type), + (updatePayload = type.dependencies), + (newProps.dependencies = + null === updatePayload + ? null + : { + lanes: updatePayload.lanes, + firstContext: updatePayload.firstContext + }), + (newProps.selfBaseDuration = type.selfBaseDuration), + (newProps.treeBaseDuration = type.treeBaseDuration)), + (renderLanes = renderLanes.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2 + ); + return workInProgress.child; + } + current = current.sibling; + } + null !== type.tail && + now() > workInProgressRootRenderTargetTime && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + } + else { + if (!newProps) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.flags |= 128), + (newProps = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)), + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && + !updatePayload.alternate) + ) + return bubbleProperties(workInProgress), null; + } else + 2 * now() - type.renderingStartTime > + workInProgressRootRenderTargetTime && + 1073741824 !== renderLanes && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = type.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (type.last = updatePayload)); + } + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; + case 22: + case 23: + return ( + popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), + null !== current && + (null !== current.memoizedState) !== renderLanes && + (workInProgress.flags |= 8192), + renderLanes && 0 !== (workInProgress.mode & 1) + ? 0 !== (subtreeRenderLanes & 1073741824) && + bubbleProperties(workInProgress) + : bubbleProperties(workInProgress), + null + ); + case 24: + return null; + case 25: + return null; + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} function unwindWork(current, workInProgress) { popTreeContext(workInProgress); switch (workInProgress.tag) { @@ -5816,16 +6032,23 @@ function unwindWork(current, workInProgress) { case 5: return popHostContext(workInProgress), null; case 13: - return ( - pop(suspenseStackCursor), - (current = workInProgress.flags), - current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress) - : null - ); + pop(suspenseStackCursor); + current = workInProgress.memoizedState; + if ( + null !== current && + null !== current.dehydrated && + null === workInProgress.alternate + ) + throw Error( + "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." + ); + current = workInProgress.flags; + return current & 65536 + ? ((workInProgress.flags = (current & -65537) | 128), + 0 !== (workInProgress.mode & 2) && + transferActualDuration(workInProgress), + workInProgress) + : null; case 19: return pop(suspenseStackCursor), null; case 4: @@ -5957,8 +6180,8 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create$83 = effect.create; - effect.destroy = create$83(); + var create$81 = effect.create; + effect.destroy = create$81(); } effect = effect.next; } while (effect !== finishedWork); @@ -5980,48 +6203,129 @@ function detachFiberAfterEffects(fiber) { fiber.stateNode = null; fiber.updateQueue = null; } -function commitWork(current, finishedWork) { - switch (finishedWork.tag) { +function recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + parent +) { + for (parent = parent.child; null !== parent; ) + commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, parent), + (parent = parent.sibling); +} +function commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + deletedFiber +) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) + try { + injectedHook.onCommitFiberUnmount(rendererID, deletedFiber); + } catch (err) {} + switch (deletedFiber.tag) { + case 5: + safelyDetachRef(deletedFiber, nearestMountedAncestor); + case 6: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 18: + break; + case 4: + createChildNodeSet(deletedFiber.stateNode.containerInfo); + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; case 0: case 11: case 14: case 15: - commitHookEffectListUnmount(3, finishedWork, finishedWork.return); - commitHookEffectListMount(3, finishedWork); - if (finishedWork.mode & 2) + var updateQueue = deletedFiber.updateQueue; + if ( + null !== updateQueue && + ((updateQueue = updateQueue.lastEffect), null !== updateQueue) + ) { + var effect = (updateQueue = updateQueue.next); + do { + var _effect = effect, + destroy = _effect.destroy; + _effect = _effect.tag; + void 0 !== destroy && + (0 !== (_effect & 2) + ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) + : 0 !== (_effect & 4) && + (deletedFiber.mode & 2 + ? (startLayoutEffectTimer(), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ), + recordLayoutEffectDuration(deletedFiber)) + : safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ))); + effect = effect.next; + } while (effect !== updateQueue); + } + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 1: + safelyDetachRef(deletedFiber, nearestMountedAncestor); + updateQueue = deletedFiber.stateNode; + if ("function" === typeof updateQueue.componentWillUnmount) try { - startLayoutEffectTimer(), - commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - } finally { - recordLayoutEffectDuration(finishedWork); + if ( + ((updateQueue.props = deletedFiber.memoizedProps), + (updateQueue.state = deletedFiber.memoizedState), + deletedFiber.mode & 2) + ) + try { + startLayoutEffectTimer(), updateQueue.componentWillUnmount(); + } finally { + recordLayoutEffectDuration(deletedFiber); + } + else updateQueue.componentWillUnmount(); + } catch (error) { + captureCommitPhaseError(deletedFiber, nearestMountedAncestor, error); } - else commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - return; - case 12: - return; - case 13: - attachSuspenseRetryListeners(finishedWork); - return; - case 19: - attachSuspenseRetryListeners(finishedWork); - return; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 21: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; case 22: - case 23: - return; - } - a: { - switch (finishedWork.tag) { - case 1: - case 5: - case 6: - break a; - case 3: - case 4: - break a; - } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + default: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -6047,173 +6351,129 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function commitMutationEffects(root, firstChild, committedLanes) { +function commitMutationEffects(root, finishedWork, committedLanes) { inProgressLanes = committedLanes; inProgressRoot = root; - for (nextEffect = firstChild; null !== nextEffect; ) { - root = nextEffect; - firstChild = root.deletions; - if (null !== firstChild) - for ( - committedLanes = 0; - committedLanes < firstChild.length; - committedLanes++ - ) { - var childToDelete = firstChild[committedLanes]; - try { - a: for (var node = childToDelete; ; ) { - var current = node; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, current); - } catch (err) {} - switch (current.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = current.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next, - effect = firstEffect; - do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; - void 0 !== destroy && - (0 !== (tag & 2) - ? safelyCallDestroy(current, root, destroy) - : 0 !== (tag & 4) && - (current.mode & 2 - ? (startLayoutEffectTimer(), - safelyCallDestroy(current, root, destroy), - recordLayoutEffectDuration(current)) - : safelyCallDestroy(current, root, destroy))); - effect = effect.next; - } while (effect !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(current, root); - var instance = current.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - if ( - ((effect = current), - (_effect = instance), - (_effect.props = effect.memoizedProps), - (_effect.state = effect.memoizedState), - effect.mode & 2) - ) - try { - startLayoutEffectTimer(), - _effect.componentWillUnmount(); - } finally { - recordLayoutEffectDuration(effect); - } - else _effect.componentWillUnmount(); - } catch (error) { - captureCommitPhaseError(current, root, error); - } - break; - case 5: - safelyDetachRef(current, root); - break; - case 4: - createChildNodeSet(current.stateNode.containerInfo); - } - if (null !== node.child) - (node.child.return = node), (node = node.child); - else { - if (node === childToDelete) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === childToDelete) - break a; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } - } - var alternate = childToDelete.alternate; - null !== alternate && (alternate.return = null); - childToDelete.return = null; - } catch (error) { - captureCommitPhaseError(childToDelete, root, error); - } - } - firstChild = root.child; - if (0 !== (root.subtreeFlags & 12854) && null !== firstChild) - (firstChild.return = root), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - var flags = root.flags; - if (flags & 512) { - var current$jscomp$0 = root.alternate; - if (null !== current$jscomp$0) { - firstChild = current$jscomp$0; - var currentRef = firstChild.ref; - if (null !== currentRef) - if ("function" === typeof currentRef) - if (firstChild.mode & 2) - try { - startLayoutEffectTimer(), currentRef(null); - } finally { - recordLayoutEffectDuration(firstChild); - } - else currentRef(null); - else currentRef.current = null; - } - } - if (flags & 8192) - switch (root.tag) { - case 13: - if (null !== root.memoizedState) { - var current$89 = root.alternate; - if (null === current$89 || null === current$89.memoizedState) - globalMostRecentFallbackTime = now(); - } - } - switch (flags & 4102) { - case 2: - root.flags &= -3; - break; - case 6: - root.flags &= -3; - commitWork(root.alternate, root); - break; - case 4096: - root.flags &= -4097; - break; - case 4100: - root.flags &= -4097; - commitWork(root.alternate, root); - break; - case 4: - commitWork(root.alternate, root); - } - } catch (error) { - captureCommitPhaseError(root, root.return, error); - } - firstChild = root.sibling; - if (null !== firstChild) { - firstChild.return = root.return; - nextEffect = firstChild; - break; - } - nextEffect = root.return; - } - } + commitMutationEffectsOnFiber(finishedWork, root); inProgressRoot = inProgressLanes = null; } +function recursivelyTraverseMutationEffects(root, parentFiber) { + var deletions = parentFiber.deletions; + if (null !== deletions) + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; + try { + commitDeletionEffectsOnFiber(root, parentFiber, childToDelete); + var alternate = childToDelete.alternate; + null !== alternate && (alternate.return = null); + childToDelete.return = null; + } catch (error) { + captureCommitPhaseError(childToDelete, parentFiber, error); + } + } + if (parentFiber.subtreeFlags & 12854) + for (parentFiber = parentFiber.child; null !== parentFiber; ) + commitMutationEffectsOnFiber(parentFiber, root), + (parentFiber = parentFiber.sibling); +} +function commitMutationEffectsOnFiber(finishedWork, root) { + var current = finishedWork.alternate, + flags = finishedWork.flags; + switch (finishedWork.tag) { + case 0: + case 11: + case 14: + case 15: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & 4) { + try { + commitHookEffectListUnmount(3, finishedWork, finishedWork.return), + commitHookEffectListMount(3, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + if (finishedWork.mode & 2) { + try { + startLayoutEffectTimer(), + commitHookEffectListUnmount(5, finishedWork, finishedWork.return); + } catch (error$87) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error$87 + ); + } + recordLayoutEffectDuration(finishedWork); + } else + try { + commitHookEffectListUnmount(5, finishedWork, finishedWork.return); + } catch (error$88) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error$88 + ); + } + } + break; + case 1: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 512 && + null !== current && + safelyDetachRef(current, current.return); + break; + case 5: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 512 && + null !== current && + safelyDetachRef(current, current.return); + break; + case 6: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 3: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 4: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 13: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + root = finishedWork.child; + root.flags & 8192 && + null !== root.memoizedState && + (null === root.alternate || null === root.alternate.memoizedState) && + (globalMostRecentFallbackTime = now()); + flags & 4 && attachSuspenseRetryListeners(finishedWork); + break; + case 22: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 19: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 4 && attachSuspenseRetryListeners(finishedWork); + break; + case 21: + break; + default: + recursivelyTraverseMutationEffects(root, finishedWork), + commitReconciliationEffects(finishedWork); + } +} +function commitReconciliationEffects(finishedWork) { + var flags = finishedWork.flags; + flags & 2 && (finishedWork.flags &= -3); + flags & 4096 && (finishedWork.flags &= -4097); +} function commitLayoutEffects(finishedWork, root, committedLanes) { inProgressLanes = committedLanes; inProgressRoot = root; @@ -6288,22 +6548,22 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { commitUpdateQueue(committedLanes, updateQueue, instance); break; case 3: - var updateQueue$85 = committedLanes.updateQueue; - if (null !== updateQueue$85) { - var instance$86 = null; + var updateQueue$83 = committedLanes.updateQueue; + if (null !== updateQueue$83) { + var instance$84 = null; if (null !== committedLanes.child) switch (committedLanes.child.tag) { case 5: - instance$86 = + instance$84 = committedLanes.child.stateNode.canonical; break; case 1: - instance$86 = committedLanes.child.stateNode; + instance$84 = committedLanes.child.stateNode; } commitUpdateQueue( committedLanes, - updateQueue$85, - instance$86 + updateQueue$83, + instance$84 ); } break; @@ -6322,7 +6582,7 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { onCommit = _finishedWork$memoize2.onCommit, onRender = _finishedWork$memoize2.onRender, effectDuration = committedLanes.stateNode.effectDuration; - instance$86 = commitTime; + instance$84 = commitTime; current = null === current ? "mount" : "update"; currentUpdateIsNested && (current = "nested-update"); "function" === typeof onRender && @@ -6332,14 +6592,14 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { committedLanes.actualDuration, committedLanes.treeBaseDuration, committedLanes.actualStartTime, - instance$86 + instance$84 ); "function" === typeof onCommit && onCommit( committedLanes.memoizedProps.id, current, effectDuration, - instance$86 + instance$84 ); enqueuePendingPassiveProfilerEffect(committedLanes); var parentFiber = committedLanes.return; @@ -6362,6 +6622,7 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { case 21: case 22: case 23: + case 25: break; default: throw Error( @@ -6369,27 +6630,27 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { ); } if (committedLanes.flags & 512) { - instance$86 = void 0; + instance$84 = void 0; current = committedLanes; var ref = current.ref; if (null !== ref) { var instance$jscomp$0 = current.stateNode; switch (current.tag) { case 5: - instance$86 = instance$jscomp$0.canonical; + instance$84 = instance$jscomp$0.canonical; break; default: - instance$86 = instance$jscomp$0; + instance$84 = instance$jscomp$0; } if ("function" === typeof ref) if (current.mode & 2) try { - startLayoutEffectTimer(), ref(instance$86); + startLayoutEffectTimer(), ref(instance$84); } finally { recordLayoutEffectDuration(current); } - else ref(instance$86); - else ref.current = instance$86; + else ref(instance$84); + else ref.current = instance$84; } } } catch (error) { @@ -6404,10 +6665,10 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { nextEffect = null; break; } - instance$86 = committedLanes.sibling; - if (null !== instance$86) { - instance$86.return = committedLanes.return; - nextEffect = instance$86; + instance$84 = committedLanes.sibling; + if (null !== instance$84) { + instance$84.return = committedLanes.return; + nextEffect = instance$84; break; } nextEffect = committedLanes.return; @@ -6433,6 +6694,7 @@ var ceil = Math.ceil, workInProgressRootRecoverableErrors = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, + workInProgressTransitions = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -6458,10 +6720,7 @@ function requestUpdateLane(fiber) { if (null !== ReactCurrentBatchConfig.transition) return ( 0 === currentEventTransitionLane && - ((fiber = nextTransitionLane), - (nextTransitionLane <<= 1), - 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64), - (currentEventTransitionLane = fiber)), + (currentEventTransitionLane = claimNextTransitionLane()), currentEventTransitionLane ); fiber = currentUpdatePriority; @@ -6518,6 +6777,13 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { (sourceFiber = sourceFiber.return); return 3 === alternate.tag ? alternate.stateNode : null; } +function isInterleavedUpdate(fiber) { + return ( + (null !== workInProgressRoot || null !== interleavedQueues) && + 0 !== (fiber.mode & 1) && + 0 === (executionContext & 2) + ); +} function ensureRootIsScheduled(root, currentTime) { for ( var existingCallbackNode = root.callbackNode, @@ -6621,6 +6887,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { memoizedUpdaters.clear()); movePendingFibersToMemoized(root, didTimeout); } + workInProgressTransitions = null; workInProgressRootRenderTargetTime = now() + 500; prepareFreshStack(root, didTimeout); } @@ -6679,7 +6946,11 @@ function performConcurrentWorkOnRoot(root, didTimeout) { case 1: throw Error("Root did not complete. This is a bug in React."); case 2: - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 3: markRootSuspended$1(root, lanes); @@ -6696,12 +6967,21 @@ function performConcurrentWorkOnRoot(root, didTimeout) { break; } root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), didTimeout ); break; } - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 4: markRootSuspended$1(root, lanes); @@ -6732,15 +7012,28 @@ function performConcurrentWorkOnRoot(root, didTimeout) { : 1960 * ceil(lanes / 1960)) - lanes; if (10 < lanes) { root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), lanes ); break; } - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 5: - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; default: throw Error("Unknown root exit status."); @@ -6760,15 +7053,17 @@ function recoverFromConcurrentError(root, errorRetryLanes) { 2 !== root && ((errorRetryLanes = workInProgressRootRecoverableErrors), (workInProgressRootRecoverableErrors = errorsFromFirstAttempt), - null !== errorRetryLanes && - (null === workInProgressRootRecoverableErrors - ? (workInProgressRootRecoverableErrors = errorRetryLanes) - : workInProgressRootRecoverableErrors.push.apply( - workInProgressRootRecoverableErrors, - errorRetryLanes - ))); + null !== errorRetryLanes && queueRecoverableErrors(errorRetryLanes)); return root; } +function queueRecoverableErrors(errors) { + null === workInProgressRootRecoverableErrors + ? (workInProgressRootRecoverableErrors = errors) + : workInProgressRootRecoverableErrors.push.apply( + workInProgressRootRecoverableErrors, + errors + ); +} function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { if (node.flags & 16384) { @@ -6840,7 +7135,11 @@ function performSyncWorkOnRoot(root) { throw Error("Root did not complete. This is a bug in React."); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); ensureRootIsScheduled(root, now()); return null; } @@ -7079,12 +7378,12 @@ function handleError(root$jscomp$0, thrownValue) { root.flags |= 65536; thrownValue &= -thrownValue; root.lanes |= thrownValue; - var update$33 = createClassErrorUpdate( + var update$34 = createClassErrorUpdate( root, wakeable, thrownValue ); - enqueueCapturedUpdate(root, update$33); + enqueueCapturedUpdate(root, update$34); break a; } } @@ -7131,6 +7430,7 @@ function renderRootSync(root, lanes) { memoizedUpdaters.clear()); movePendingFibersToMemoized(root, lanes); } + workInProgressTransitions = null; prepareFreshStack(root, lanes); } do @@ -7225,50 +7525,60 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors) { +function commitRoot(root, recoverableErrors, transitions) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$2.transition; try { (ReactCurrentBatchConfig$2.transition = null), (currentUpdatePriority = 1), - commitRootImpl(root, recoverableErrors, previousUpdateLanePriority); + commitRootImpl( + root, + recoverableErrors, + transitions, + previousUpdateLanePriority + ); } finally { (ReactCurrentBatchConfig$2.transition = prevTransition), (currentUpdatePriority = previousUpdateLanePriority); } return null; } -function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { +function commitRootImpl( + root, + recoverableErrors, + transitions, + renderPriorityLevel +) { do flushPassiveEffects(); while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 6)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - if (null === finishedWork) return null; + transitions = root.finishedWork; + var lanes = root.finishedLanes; + if (null === transitions) return null; root.finishedWork = null; root.finishedLanes = 0; - if (finishedWork === root.current) + if (transitions === root.current) throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; root.callbackPriority = 0; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + var remainingLanes = transitions.lanes | transitions.childLanes; markRootFinished(root, remainingLanes); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 2064) && - 0 === (finishedWork.flags & 2064)) || + (0 === (transitions.subtreeFlags & 2064) && + 0 === (transitions.flags & 2064)) || rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), scheduleCallback$1(NormalPriority, function() { flushPassiveEffects(); return null; })); - remainingLanes = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || remainingLanes) { + remainingLanes = 0 !== (transitions.flags & 15990); + if (0 !== (transitions.subtreeFlags & 15990) || remainingLanes) { remainingLanes = ReactCurrentBatchConfig$2.transition; ReactCurrentBatchConfig$2.transition = null; var previousPriority = currentUpdatePriority; @@ -7276,32 +7586,32 @@ function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { var prevExecutionContext = executionContext; executionContext |= 4; ReactCurrentOwner$2.current = null; - commitBeforeMutationEffects(root, finishedWork); + commitBeforeMutationEffects(root, transitions); commitTime = now$1(); - commitMutationEffects(root, finishedWork, lanes); - root.current = finishedWork; - commitLayoutEffects(finishedWork, root, lanes); + commitMutationEffects(root, transitions, lanes); + root.current = transitions; + commitLayoutEffects(transitions, root, lanes); requestPaint(); executionContext = prevExecutionContext; currentUpdatePriority = previousPriority; ReactCurrentBatchConfig$2.transition = remainingLanes; - } else (root.current = finishedWork), (commitTime = now$1()); + } else (root.current = transitions), (commitTime = now$1()); rootDoesHavePassiveEffects && ((rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + onCommitRoot(transitions.stateNode, renderPriorityLevel); isDevToolsPresent && root.memoizedUpdaters.clear(); ensureRootIsScheduled(root, now()); if (null !== recoverableErrors) for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ + renderPriorityLevel = root.onRecoverableError, transitions = 0; + transitions < recoverableErrors.length; + transitions++ ) - renderPriorityLevel(recoverableErrors[finishedWork]); + renderPriorityLevel(recoverableErrors[transitions]); if (hasUncaughtError) throw ((hasUncaughtError = !1), (root = firstUncaughtError), @@ -7602,21 +7912,43 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { : (workInProgressRootPingedLanes |= pingedLanes)); ensureRootIsScheduled(root, wakeable); } -function resolveRetryWakeable(boundaryFiber, wakeable) { - var retryCache = boundaryFiber.stateNode; - null !== retryCache && retryCache.delete(wakeable); - wakeable = 0; - 0 === wakeable && +function retryTimedOutBoundary(boundaryFiber, retryLane) { + 0 === retryLane && (0 === (boundaryFiber.mode & 1) - ? (wakeable = 1) - : ((wakeable = nextRetryLane), + ? (retryLane = 1) + : ((retryLane = nextRetryLane), (nextRetryLane <<= 1), 0 === (nextRetryLane & 130023424) && (nextRetryLane = 4194304))); - retryCache = requestEventTime(); - boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); + var eventTime = requestEventTime(); + boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane); null !== boundaryFiber && - (markRootUpdated(boundaryFiber, wakeable, retryCache), - ensureRootIsScheduled(boundaryFiber, retryCache)); + (markRootUpdated(boundaryFiber, retryLane, eventTime), + ensureRootIsScheduled(boundaryFiber, eventTime)); +} +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState, + retryLane = 0; + null !== suspenseState && (retryLane = suspenseState.retryLane); + retryTimedOutBoundary(boundaryFiber, retryLane); +} +function resolveRetryWakeable(boundaryFiber, wakeable) { + var retryLane = 0; + switch (boundaryFiber.tag) { + case 13: + var retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + null !== suspenseState && (retryLane = suspenseState.retryLane); + break; + case 19: + retryCache = boundaryFiber.stateNode; + break; + default: + throw Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ); + } + null !== retryCache && retryCache.delete(wakeable); + retryTimedOutBoundary(boundaryFiber, retryLane); } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { @@ -7646,10 +7978,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { switch (workInProgress.tag) { case 2: var Component = workInProgress.type; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; var context = getMaskedContext( workInProgress, @@ -7703,10 +8032,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 16: Component = workInProgress.elementType; a: { - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; context = Component._init; Component = context(Component._payload); @@ -7812,7 +8138,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return ( pushHostContext(workInProgress), (Component = workInProgress.pendingProps.children), - markRef$1(current, workInProgress), + markRef(current, workInProgress), reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); @@ -7910,24 +8236,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - newValue = workInProgress.child, - null !== newValue && (newValue.return = workInProgress); - null !== newValue; + hasContext = workInProgress.child, + null !== hasContext && (hasContext.return = workInProgress); + null !== hasContext; ) { - var list = newValue.dependencies; + var list = hasContext.dependencies; if (null !== list) { - hasContext = newValue.child; + newValue = hasContext.child; for ( var dependency = list.firstContext; null !== dependency; ) { if (dependency.context === Component) { - if (1 === newValue.tag) { + if (1 === hasContext.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; - var updateQueue = newValue.updateQueue; + var updateQueue = hasContext.updateQueue; if (null !== updateQueue) { updateQueue = updateQueue.shared; var pending = updateQueue.pending; @@ -7938,11 +8264,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateQueue.pending = dependency; } } - newValue.lanes |= renderLanes; - dependency = newValue.alternate; + hasContext.lanes |= renderLanes; + dependency = hasContext.alternate; null !== dependency && (dependency.lanes |= renderLanes); scheduleContextWorkOnParentPath( - newValue.return, + hasContext.return, renderLanes, workInProgress ); @@ -7951,29 +8277,43 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } dependency = dependency.next; } - } else - hasContext = - 10 === newValue.tag - ? newValue.type === workInProgress.type - ? null - : newValue.child - : newValue.child; - if (null !== hasContext) hasContext.return = newValue; + } else if (10 === hasContext.tag) + newValue = + hasContext.type === workInProgress.type + ? null + : hasContext.child; + else if (18 === hasContext.tag) { + newValue = hasContext.return; + if (null === newValue) + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + newValue.lanes |= renderLanes; + list = newValue.alternate; + null !== list && (list.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + newValue, + renderLanes, + workInProgress + ); + newValue = hasContext.sibling; + } else newValue = hasContext.child; + if (null !== newValue) newValue.return = hasContext; else - for (hasContext = newValue; null !== hasContext; ) { - if (hasContext === workInProgress) { - hasContext = null; + for (newValue = hasContext; null !== newValue; ) { + if (newValue === workInProgress) { + newValue = null; break; } - newValue = hasContext.sibling; - if (null !== newValue) { - newValue.return = hasContext.return; - hasContext = newValue; + hasContext = newValue.sibling; + if (null !== hasContext) { + hasContext.return = newValue.return; + newValue = hasContext; break; } - hasContext = hasContext.return; + newValue = newValue.return; } - newValue = hasContext; + hasContext = newValue; } reconcileChildren( current, @@ -8024,10 +8364,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress.elementType === Component ? context : resolveDefaultProps(Component, context)), - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)), + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), (workInProgress.tag = 1), isContextProvider(Component) ? ((current = !0), pushContextProvider(workInProgress)) @@ -8385,10 +8722,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_974 = { + devToolsConfig$jscomp$inline_968 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "18.0.0-experimental-34aa5cfe0-20220329", + version: "18.2.0-next-d300cebde-20220601", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8403,11 +8740,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1238 = { - bundleType: devToolsConfig$jscomp$inline_974.bundleType, - version: devToolsConfig$jscomp$inline_974.version, - rendererPackageName: devToolsConfig$jscomp$inline_974.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_974.rendererConfig, +var internals$jscomp$inline_1234 = { + bundleType: devToolsConfig$jscomp$inline_968.bundleType, + version: devToolsConfig$jscomp$inline_968.version, + rendererPackageName: devToolsConfig$jscomp$inline_968.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_968.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8423,26 +8760,26 @@ var internals$jscomp$inline_1238 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_974.findFiberByHostInstance || + devToolsConfig$jscomp$inline_968.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.0.0-experimental-34aa5cfe0-20220329" + reconcilerVersion: "18.2.0-next-d300cebde-20220601" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1239 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1235 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1239.isDisabled && - hook$jscomp$inline_1239.supportsFiber + !hook$jscomp$inline_1235.isDisabled && + hook$jscomp$inline_1235.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1239.inject( - internals$jscomp$inline_1238 + (rendererID = hook$jscomp$inline_1235.inject( + internals$jscomp$inline_1234 )), - (injectedHook = hook$jscomp$inline_1239); + (injectedHook = hook$jscomp$inline_1235); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -8499,7 +8836,8 @@ exports.render = function(element, containerTag, callback, concurrentRoot) { element: null, isDehydrated: !1, cache: null, - transitions: null + transitions: null, + pendingSuspenseBoundaries: null }), initializeUpdateQueue(root), (root = concurrentRoot), diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js index fb9a73c8ddb..18a204692a6 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactNativeRenderer-dev * @preventMunge - * @generated SignedSource<<241f2ea4a27fb05d58e884b59ece93fe>> + * @generated SignedSource<<8a3af3b821da6ecad0d3cd1faee60e8f>> */ 'use strict'; @@ -3064,7 +3064,6 @@ function set(key, value) { var enableSchedulingProfiler = false; var enableProfilerTimer = true; var enableProfilerCommitHooks = true; -var enableLazyElements = false; var warnAboutStringRefs = false; var enableSuspenseAvoidThisFallback = false; var enableNewReconciler = false; @@ -3327,9 +3326,6 @@ var Placement = var Update = /* */ 4; -var PlacementAndUpdate = - /* */ - Placement | Update; var ChildDeletion = /* */ 16; @@ -3357,9 +3353,6 @@ var Passive = var Hydrating = /* */ 4096; -var HydratingAndUpdate = - /* */ - Hydrating | Update; var Visibility = /* */ 8192; @@ -4518,13 +4511,13 @@ var InputContinuousHydrationLane = /* */ 2; var InputContinuousLane = - /* */ + /* */ 4; var DefaultHydrationLane = /* */ 8; var DefaultLane = - /* */ + /* */ 16; var TransitionHydrationLane = /* */ @@ -4603,13 +4596,13 @@ var SelectiveHydrationLane = /* */ 134217728; var NonIdleLanes = - /* */ + /* */ 268435455; var IdleHydrationLane = /* */ 268435456; var IdleLane = - /* */ + /* */ 536870912; var OffscreenLane = /* */ @@ -4942,6 +4935,10 @@ function includesNonIdleWork(lanes) { function includesOnlyRetries(lanes) { return (lanes & RetryLanes) === lanes; } +function includesOnlyNonUrgentLanes(lanes) { + var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane; + return (lanes & UrgentLanes) === NoLanes; +} function includesOnlyTransitions(lanes) { return (lanes & TransitionLanes) === lanes; } @@ -4959,7 +4956,7 @@ function includesExpiredLane(root, lanes) { return (lanes & root.expiredLanes) !== NoLanes; } function isTransitionLane(lane) { - return (lane & TransitionLanes) !== 0; + return (lane & TransitionLanes) !== NoLanes; } function claimNextTransitionLane() { // Cycle through the lanes, assigning each new transition to the next lane. @@ -4968,7 +4965,7 @@ function claimNextTransitionLane() { var lane = nextTransitionLane; nextTransitionLane <<= 1; - if ((nextTransitionLane & TransitionLanes) === 0) { + if ((nextTransitionLane & TransitionLanes) === NoLanes) { nextTransitionLane = TransitionLane1; } @@ -4978,7 +4975,7 @@ function claimNextRetryLane() { var lane = nextRetryLane; nextRetryLane <<= 1; - if ((nextRetryLane & RetryLanes) === 0) { + if ((nextRetryLane & RetryLanes) === NoLanes) { nextRetryLane = RetryLane1; } @@ -5080,8 +5077,8 @@ function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; // Let's try everything again - root.suspendedLanes = 0; - root.pingedLanes = 0; + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; root.expiredLanes &= remainingLanes; root.mutableReadLanes &= remainingLanes; root.entangledLanes &= remainingLanes; @@ -5131,6 +5128,63 @@ function markRootEntangled(root, entangledLanes) { lanes &= ~lane; } } +function getBumpedLaneForHydration(root, renderLanes) { + var renderLane = getHighestPriorityLane(renderLanes); + var lane; + + switch (renderLane) { + case InputContinuousLane: + lane = InputContinuousHydrationLane; + break; + + case DefaultLane: + lane = DefaultHydrationLane; + break; + + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + case TransitionLane15: + case TransitionLane16: + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + case RetryLane5: + lane = TransitionHydrationLane; + break; + + case IdleLane: + lane = IdleHydrationLane; + break; + + default: + // Everything else is already either a hydration lane, or shouldn't + // be retried at a hydration lane. + lane = NoLane; + break; + } // Check if the lane we chose is suspended. If so, that indicates that we + // already attempted and failed to hydrate at that level. Also check if we're + // already rendering that lane, which is rare but could happen. + + if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) { + // Give up trying to hydrate and fall back to client render. + return NoLane; + } + + return lane; +} function addFiberToLanesMap(root, fiber, lanes) { if (!isDevToolsPresent) { return; @@ -5173,6 +5227,11 @@ function movePendingFibersToMemoized(root, lanes) { lanes &= ~lane; } } +function getTransitionsForLanes(root, lanes) { + { + return null; + } +} var DiscreteEventPriority = SyncLane; var ContinuousEventPriority = InputContinuousLane; @@ -5223,7 +5282,11 @@ function shim() { } // Hydration (when unsupported) var isSuspenseInstancePending = shim; var isSuspenseInstanceFallback = shim; +var getSuspenseInstanceFallbackErrorDetails = shim; +var registerSuspenseInstanceRetry = shim; var hydrateTextInstance = shim; +var clearSuspenseBoundary = shim; +var clearSuspenseBoundaryFromContainer = shim; var errorHydratingContainer = shim; var getViewConfigForType = @@ -6227,6 +6290,125 @@ function isRootDehydrated(root) { return currentState.isDehydrated; } +// TODO: Use the unified fiber stack module instead of this local one? +// Intentionally not using it yet to derisk the initial implementation, because +// the way we push/pop these values is a bit unusual. If there's a mistake, I'd +// rather the ids be wrong than crash the whole reconciler. +var forkStack = []; +var forkStackIndex = 0; +var treeForkProvider = null; +var treeForkCount = 0; +var idStack = []; +var idStackIndex = 0; +var treeContextProvider = null; +var treeContextId = 1; +var treeContextOverflow = ""; + +function popTreeContext(workInProgress) { + // Restore the previous values. + // This is a bit more complicated than other context-like modules in Fiber + // because the same Fiber may appear on the stack multiple times and for + // different reasons. We have to keep popping until the work-in-progress is + // no longer at the top of the stack. + while (workInProgress === treeForkProvider) { + treeForkProvider = forkStack[--forkStackIndex]; + forkStack[forkStackIndex] = null; + treeForkCount = forkStack[--forkStackIndex]; + forkStack[forkStackIndex] = null; + } + + while (workInProgress === treeContextProvider) { + treeContextProvider = idStack[--idStackIndex]; + idStack[idStackIndex] = null; + treeContextOverflow = idStack[--idStackIndex]; + idStack[idStackIndex] = null; + treeContextId = idStack[--idStackIndex]; + idStack[idStackIndex] = null; + } +} + +var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches +// due to earlier mismatches or a suspended fiber. + +var didSuspendOrErrorDEV = false; // Hydration errors that were thrown inside this boundary + +var hydrationErrors = null; +function didSuspendOrErrorWhileHydratingDEV() { + { + return didSuspendOrErrorDEV; + } +} + +function reenterHydrationStateFromDehydratedSuspenseInstance( + fiber, + suspenseInstance, + treeContext +) { + { + return false; + } +} + +function prepareToHydrateHostInstance( + fiber, + rootContainerInstance, + hostContext +) { + { + throw new Error( + "Expected prepareToHydrateHostInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } +} + +function prepareToHydrateHostTextInstance(fiber) { + { + throw new Error( + "Expected prepareToHydrateHostTextInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } + var shouldUpdate = hydrateTextInstance(); +} + +function prepareToHydrateHostSuspenseInstance(fiber) { + { + throw new Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + } +} + +function popHydrationState(fiber) { + { + return false; + } +} + +function upgradeHydrationErrorsToRecoverable() { + if (hydrationErrors !== null) { + // Successfully completed a forced client render. The errors that occurred + // during the hydration attempt are now recovered. We will log them in + // commit phase, once the entire tree has finished. + queueRecoverableErrors(hydrationErrors); + hydrationErrors = null; + } +} + +function getIsHydrating() { + return isHydrating; +} + +function queueHydrationError(error) { + if (hydrationErrors === null) { + hydrationErrors = [error]; + } else { + hydrationErrors.push(error); + } +} + var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = null; function requestCurrentTransition() { @@ -6362,11 +6544,17 @@ function resetCurrentFiber() { } function setCurrentFiber(fiber) { { - ReactDebugCurrentFrame$1.getCurrentStack = getCurrentFiberStackInDev; + ReactDebugCurrentFrame$1.getCurrentStack = + fiber === null ? null : getCurrentFiberStackInDev; current = fiber; isRendering = false; } } +function getCurrentFiber() { + { + return current; + } +} function setIsRendering(rendering) { { isRendering = rendering; @@ -7006,6 +7194,34 @@ function propagateContextChange_eager(workInProgress, context, renderLanes) { } else if (fiber.tag === ContextProvider) { // Don't scan deeper if this is a matching provider nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + } else if (fiber.tag === DehydratedFragment) { + // If a dehydrated suspense boundary is in this subtree, we don't know + // if it will have any context consumers in it. The best we can do is + // mark it as having updates. + var parentSuspense = fiber.return; + + if (parentSuspense === null) { + throw new Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + } + + parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes); + var _alternate = parentSuspense.alternate; + + if (_alternate !== null) { + _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes); + } // This is intentionally passing this fiber as the parent + // because we want to schedule this fiber as having work + // on its children. We'll use the childLanes on + // this fiber to indicate that a context has changed. + + scheduleContextWorkOnParentPath( + parentSuspense, + renderLanes, + workInProgress + ); + nextFiber = fiber.sibling; } else { // Traverse down. nextFiber = fiber.child; @@ -7122,6 +7338,9 @@ function pushInterleavedQueue(queue) { interleavedQueues.push(queue); } } +function hasInterleavedUpdates() { + return interleavedQueues !== null; +} function enqueueInterleavedUpdates() { // Transfer the interleaved updates onto the main queue. Each queue has a // `pending` field and an `interleaved` field. When they are not null, they @@ -8745,78 +8964,6 @@ function updateClassInstance( return shouldUpdate; } -// TODO: Use the unified fiber stack module instead of this local one? -// Intentionally not using it yet to derisk the initial implementation, because -// the way we push/pop these values is a bit unusual. If there's a mistake, I'd -// rather the ids be wrong than crash the whole reconciler. -var forkStack = []; -var forkStackIndex = 0; -var treeForkProvider = null; -var treeForkCount = 0; -var idStack = []; -var idStackIndex = 0; -var treeContextProvider = null; -var treeContextId = 1; -var treeContextOverflow = ""; - -function popTreeContext(workInProgress) { - // Restore the previous values. - // This is a bit more complicated than other context-like modules in Fiber - // because the same Fiber may appear on the stack multiple times and for - // different reasons. We have to keep popping until the work-in-progress is - // no longer at the top of the stack. - while (workInProgress === treeForkProvider) { - treeForkProvider = forkStack[--forkStackIndex]; - forkStack[forkStackIndex] = null; - treeForkCount = forkStack[--forkStackIndex]; - forkStack[forkStackIndex] = null; - } - - while (workInProgress === treeContextProvider) { - treeContextProvider = idStack[--idStackIndex]; - idStack[idStackIndex] = null; - treeContextOverflow = idStack[--idStackIndex]; - idStack[idStackIndex] = null; - treeContextId = idStack[--idStackIndex]; - idStack[idStackIndex] = null; - } -} - -var isHydrating = false; - -function prepareToHydrateHostInstance( - fiber, - rootContainerInstance, - hostContext -) { - { - throw new Error( - "Expected prepareToHydrateHostInstance() to never be called. " + - "This error is likely caused by a bug in React. Please file an issue." - ); - } -} - -function prepareToHydrateHostTextInstance(fiber) { - { - throw new Error( - "Expected prepareToHydrateHostTextInstance() to never be called. " + - "This error is likely caused by a bug in React. Please file an issue." - ); - } - var shouldUpdate = hydrateTextInstance(); -} - -function popHydrationState(fiber) { - { - return false; - } -} - -function getIsHydrating() { - return isHydrating; -} - var didWarnAboutMaps; var didWarnAboutGenerators; var didWarnAboutStringRefs; @@ -9029,6 +9176,12 @@ function warnOnFunctionType(returnFiber) { ); } } + +function resolveLazy(lazyType) { + var payload = lazyType._payload; + var init = lazyType._init; + return init(payload); +} // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. @@ -9170,7 +9323,10 @@ function ChildReconciler(shouldTrackSideEffects) { // We need to do this after the Hot Reloading check above, // because hot reloading has different semantics than prod because // it doesn't resuspend. So we can't let the call below suspend. - enableLazyElements + (typeof elementType === "object" && + elementType !== null && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === current.type) ) { // Move based on index var existing = useFiber(current, element.props); @@ -9267,6 +9423,12 @@ function ChildReconciler(shouldTrackSideEffects) { _created2.return = returnFiber; return _created2; } + + case REACT_LAZY_TYPE: { + var payload = newChild._payload; + var init = newChild._init; + return createChild(returnFiber, init(payload), lanes); + } } if (isArray(newChild) || getIteratorFn(newChild)) { @@ -9328,6 +9490,12 @@ function ChildReconciler(shouldTrackSideEffects) { return null; } } + + case REACT_LAZY_TYPE: { + var payload = newChild._payload; + var init = newChild._init; + return updateSlot(returnFiber, oldFiber, init(payload), lanes); + } } if (isArray(newChild) || getIteratorFn(newChild)) { @@ -9386,6 +9554,17 @@ function ChildReconciler(shouldTrackSideEffects) { return updatePortal(returnFiber, _matchedFiber2, newChild, lanes); } + + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + init(payload), + lanes + ); } if (isArray(newChild) || getIteratorFn(newChild)) { @@ -9452,6 +9631,12 @@ function ChildReconciler(shouldTrackSideEffects) { ); break; + + case REACT_LAZY_TYPE: + var payload = child._payload; + var init = child._init; + warnOnInvalidKey(init(payload), knownKeys, returnFiber); + break; } } @@ -9893,7 +10078,10 @@ function ChildReconciler(shouldTrackSideEffects) { // We need to do this after the Hot Reloading check above, // because hot reloading has different semantics than prod because // it doesn't resuspend. So we can't let the call below suspend. - enableLazyElements + (typeof elementType === "object" && + elementType !== null && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === child.type) ) { deleteRemainingChildren(returnFiber, child.sibling); @@ -10022,6 +10210,17 @@ function ChildReconciler(shouldTrackSideEffects) { lanes ) ); + + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; // TODO: This function is supposed to be non-recursive. + + return reconcileChildFibers( + returnFiber, + currentFirstChild, + init(payload), + lanes + ); } if (isArray(newChild)) { @@ -11541,66 +11740,72 @@ function updateMemo(nextCreate, deps) { } function mountDeferredValue(value) { - var _mountState = mountState(value), - prevValue = _mountState[0], - setValue = _mountState[1]; - - mountEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = mountWorkInProgressHook(); + hook.memoizedState = value; + return value; } function updateDeferredValue(value) { - var _updateState = updateState(), - prevValue = _updateState[0], - setValue = _updateState[1]; - - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + var resolvedCurrentHook = currentHook; + var prevValue = resolvedCurrentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value); } function rerenderDeferredValue(value) { - var _rerenderState = rerenderState(), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; + var hook = updateWorkInProgressHook(); - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; + if (currentHook === null) { + // This is a rerender during a mount. + hook.memoizedState = value; + return value; + } else { + // This is a rerender during an update. + var prevValue = currentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value); + } +} - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; +function updateDeferredValueImpl(hook, prevValue, value) { + var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes); + + if (shouldDeferValue) { + // This is an urgent update. If the value has changed, keep using the + // previous value and spawn a deferred render to update it later. + if (!objectIs(value, prevValue)) { + // Schedule a deferred render + var deferredLane = claimNextTransitionLane(); + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + deferredLane + ); + markSkippedUpdateLanes(deferredLane); // Set this to true to indicate that the rendered value is inconsistent + // from the latest value. The name "baseState" doesn't really match how we + // use it because we're reusing a state hook field instead of creating a + // new one. + + hook.baseState = true; + } // Reuse the previous value + + return prevValue; + } else { + // This is not an urgent update, so we can use the latest value regardless + // of what it is. No need to defer it. + // However, if we're currently inside a spawned render, then we need to mark + // this as an update to prevent the fiber from bailing out. + // + // `baseState` is true when the current value is different from the rendered + // value. The name doesn't really match how we use it because we're reusing + // a state hook field instead of creating a new one. + if (hook.baseState) { + // Flip this back to false. + hook.baseState = false; + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = value; + return value; + } } function startTransition(setPending, callback, options) { @@ -11643,9 +11848,9 @@ function startTransition(setPending, callback, options) { } function mountTransition() { - var _mountState2 = mountState(false), - isPending = _mountState2[0], - setPending = _mountState2[1]; // The `start` method never changes. + var _mountState = mountState(false), + isPending = _mountState[0], + setPending = _mountState[1]; // The `start` method never changes. var start = startTransition.bind(null, setPending); var hook = mountWorkInProgressHook(); @@ -11654,8 +11859,8 @@ function mountTransition() { } function updateTransition() { - var _updateState2 = updateState(), - isPending = _updateState2[0]; + var _updateState = updateState(), + isPending = _updateState[0]; var hook = updateWorkInProgressHook(); var start = hook.memoizedState; @@ -11663,8 +11868,8 @@ function updateTransition() { } function rerenderTransition() { - var _rerenderState2 = rerenderState(), - isPending = _rerenderState2[0]; + var _rerenderState = rerenderState(), + isPending = _rerenderState[0]; var hook = updateWorkInProgressHook(); var start = hook.memoizedState; @@ -13474,881 +13679,6 @@ function getSuspendedCache() { } // This function is called when a Suspense boundary suspends. It returns the } -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; -} - -function markRef(workInProgress) { - workInProgress.flags |= Ref; -} - -var appendAllChildren; -var updateHostContainer; -var updateHostComponent; -var updateHostText; - -{ - // Mutation mode - appendAllChildren = function( - parent, - workInProgress, - needsVisibilityToggle, - isHidden - ) { - // We only have the top Fiber that was created but we need recurse down its - // children to find all the terminal nodes. - var node = workInProgress.child; - - while (node !== null) { - if (node.tag === HostComponent || node.tag === HostText) { - appendInitialChild(parent, node.stateNode); - } else if (node.tag === HostPortal); - else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - - if (node === workInProgress) { - return; - } - - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } - - node = node.return; - } - - node.sibling.return = node.return; - node = node.sibling; - } - }; - - updateHostContainer = function(current, workInProgress) { - // Noop - }; - - updateHostComponent = function( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ) { - // If we have an alternate, that means this is an update and we need to - // schedule a side-effect to do the updates. - var oldProps = current.memoizedProps; - - if (oldProps === newProps) { - // In mutation mode, this is sufficient for a bailout because - // we won't touch this node even if children changed. - return; - } // If we get updated because one of our children updated, we don't - // have newProps so we'll have to reuse them. - // TODO: Split the update API as separate for the props vs. children. - // Even better would be if children weren't special cased at all tho. - - var instance = workInProgress.stateNode; - var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host - // component is hitting the resume path. Figure out why. Possibly - // related to `hidden`. - - var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. - - workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there - // is a new ref we mark this as an update. All the work is done in commitWork. - - if (updatePayload) { - markUpdate(workInProgress); - } - }; - - updateHostText = function(current, workInProgress, oldText, newText) { - // If the text differs, mark it as an update. All the work in done in commitWork. - if (oldText !== newText) { - markUpdate(workInProgress); - } - }; -} - -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": { - // Any insertions at the end of the tail list after this point - // should be invisible. If there are already mounted boundaries - // anything before them are not considered for collapsing. - // Therefore we need to go through the whole tail to find if - // there are any. - var tailNode = renderState.tail; - var lastTailNode = null; - - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; - } - - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. - - if (lastTailNode === null) { - // All remaining items in the tail are insertions. - renderState.tail = null; - } else { - // Detach the insertion after the last node that was already - // inserted. - lastTailNode.sibling = null; - } - - break; - } - - case "collapsed": { - // Any insertions at the end of the tail list after this point - // should be invisible. If there are already mounted boundaries - // anything before them are not considered for collapsing. - // Therefore we need to go through the whole tail to find if - // there are any. - var _tailNode = renderState.tail; - var _lastTailNode = null; - - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } - - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. - - if (_lastTailNode === null) { - // All remaining items in the tail are insertions. - if (!hasRenderedATailFallback && renderState.tail !== null) { - // We suspended during the head. We want to show at least one - // row at the tail. So we'll keep on and cut off the rest. - renderState.tail.sibling = null; - } else { - renderState.tail = null; - } - } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; - } - - break; - } - } -} - -function bubbleProperties(completedWork) { - var didBailout = - completedWork.alternate !== null && - completedWork.alternate.child === completedWork.child; - var newChildLanes = NoLanes; - var subtreeFlags = NoFlags; - - if (!didBailout) { - // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var actualDuration = completedWork.actualDuration; - var treeBaseDuration = completedWork.selfBaseDuration; - var child = completedWork.child; - - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) - ); - subtreeFlags |= child.subtreeFlags; - subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will - // only be updated if work is done on the fiber (i.e. it doesn't bailout). - // When work is done, it should bubble to the parent's actualDuration. If - // the fiber has not been cloned though, (meaning no work was done), then - // this value will reflect the amount of time spent working on a previous - // render. In that case it should not bubble. We determine whether it was - // cloned by comparing the child pointer. - - actualDuration += child.actualDuration; - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; - - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) - ); - subtreeFlags |= _child.subtreeFlags; - subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code - // smell because it assumes the commit phase is never concurrent with - // the render phase. Will address during refactor to alternate model. - - _child.return = completedWork; - _child = _child.sibling; - } - } - - completedWork.subtreeFlags |= subtreeFlags; - } else { - // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var _treeBaseDuration = completedWork.selfBaseDuration; - var _child2 = completedWork.child; - - while (_child2 !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child2.lanes, _child2.childLanes) - ); // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. - - subtreeFlags |= _child2.subtreeFlags & StaticMask; - subtreeFlags |= _child2.flags & StaticMask; - _treeBaseDuration += _child2.treeBaseDuration; - _child2 = _child2.sibling; - } - - completedWork.treeBaseDuration = _treeBaseDuration; - } else { - var _child3 = completedWork.child; - - while (_child3 !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child3.lanes, _child3.childLanes) - ); // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. - - subtreeFlags |= _child3.subtreeFlags & StaticMask; - subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code - // smell because it assumes the commit phase is never concurrent with - // the render phase. Will address during refactor to alternate model. - - _child3.return = completedWork; - _child3 = _child3.sibling; - } - } - - completedWork.subtreeFlags |= subtreeFlags; - } - - completedWork.childLanes = newChildLanes; - return didBailout; -} - -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing - // to the current tree provider fiber is just as fast and less error-prone. - // Ideally we would have a special version of the work loop only - // for hydration. - - popTreeContext(workInProgress); - - switch (workInProgress.tag) { - case IndeterminateComponent: - case LazyComponent: - case SimpleMemoComponent: - case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: - bubbleProperties(workInProgress); - return null; - - case ClassComponent: { - var Component = workInProgress.type; - - if (isContextProvider(Component)) { - popContext(workInProgress); - } - - bubbleProperties(workInProgress); - return null; - } - - case HostRoot: { - var fiberRoot = workInProgress.stateNode; - - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); - - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } - - if (current === null || current.child === null) { - // If we hydrated, pop so that we can delete any remaining children - // that weren't hydrated. - var wasHydrated = popHydrationState(); - - if (wasHydrated) { - // If we hydrated, then we'll need to schedule an update for - // the commit side-effects on the root. - markUpdate(workInProgress); - } else { - if (current !== null) { - var prevState = current.memoizedState; - - if ( - // Check if this is a client root - !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error) - (workInProgress.flags & ForceClientRender) !== NoFlags - ) { - // Schedule an effect to clear this container at the start of the - // next commit. This handles the case of React rendering into a - // container with previous children. It's also safe to do for - // updates too, because current.child would only be null if the - // previous render was null (so the container would already - // be empty). - workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been - } - } - } - } - - updateHostContainer(current, workInProgress); - bubbleProperties(workInProgress); - return null; - } - - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; - - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); - - if (current.ref !== workInProgress.ref) { - markRef(workInProgress); - } - } else { - if (!newProps) { - if (workInProgress.stateNode === null) { - throw new Error( - "We must have new props for new mounts. This error is likely " + - "caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. - - bubbleProperties(workInProgress); - return null; - } - - var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context - // "stack" as the parent. Then append children as we go in beginWork - // or completeWork depending on whether we want to add them top->down or - // bottom->up. Top->down is faster in IE11. - - var _wasHydrated = popHydrationState(); - - if (_wasHydrated) { - // TODO: Move this and createInstance step into the beginPhase - // to consolidate. - if (prepareToHydrateHostInstance()) { - // If changes to the hydrated node need to be applied at the - // commit-phase we mark this as such. - markUpdate(workInProgress); - } - } else { - var instance = createInstance( - type, - newProps, - rootContainerInstance, - currentHostContext, - workInProgress - ); - appendAllChildren(instance, workInProgress, false, false); - workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. - // (eg DOM renderer supports auto-focus for certain elements). - // Make sure such renderers get scheduled for later work. - - if (finalizeInitialChildren(instance)) { - markUpdate(workInProgress); - } - } - - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef(workInProgress); - } - } - - bubbleProperties(workInProgress); - return null; - } - - case HostText: { - var newText = newProps; - - if (current && workInProgress.stateNode != null) { - var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need - // to schedule a side-effect to do the updates. - - updateHostText(current, workInProgress, oldText, newText); - } else { - if (typeof newText !== "string") { - if (workInProgress.stateNode === null) { - throw new Error( - "We must have new props for new mounts. This error is likely " + - "caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. - } - - var _rootContainerInstance = getRootHostContainer(); - - var _currentHostContext = getHostContext(); - - var _wasHydrated2 = popHydrationState(); - - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } - - bubbleProperties(workInProgress); - return null; - } - - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; - - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. - - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } // Don't bubble properties in this case. - - return workInProgress; - } - - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; - - if (current === null); - else { - var _prevState = current.memoizedState; - prevDidTimeout = _prevState !== null; - } - // an effect to toggle the subtree's visibility. When we switch from - // fallback -> primary, the inner Offscreen fiber schedules this effect - // as part of its normal complete phase. But when we switch from - // primary -> fallback, the inner Offscreen fiber does not have a complete - // phase. So we need to schedule its effect here. - // - // We also use this flag to connect/disconnect the effects, but the same - // logic applies: when re-connecting, the Offscreen fiber's complete - // phase will handle scheduling the effect. It's only when the fallback - // is active that we have to do anything special. - - if (nextDidTimeout && !prevDidTimeout) { - var _offscreenFiber = workInProgress.child; - _offscreenFiber.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything - // in the concurrent tree already suspended during this render. - // This is a known bug. - - if ((workInProgress.mode & ConcurrentMode) !== NoMode) { - // TODO: Move this back to throwException because this is too late - // if this is a large tree which is common for initial loads. We - // don't know if we should restart a render or not until we get - // this marker, and this is too late. - // If this render already had a ping or lower pri updates, - // and this is the first time we know we're going to suspend we - // should be able to immediately restart from within throwException. - var hasInvisibleChildContext = - current === null && - (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || - !enableSuspenseAvoidThisFallback); - - if ( - hasInvisibleChildContext || - hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ) - ) { - // If this was in an invisible tree or a new render, then showing - // this boundary is ok. - renderDidSuspend(); - } else { - // Otherwise, we're going to have to hide content so we should - // suspend for longer if possible. - renderDidSuspendDelayIfPossible(); - } - } - } - - var wakeables = workInProgress.updateQueue; - - if (wakeables !== null) { - // Schedule an effect to attach a retry listener to the promise. - // TODO: Move to passive phase - workInProgress.flags |= Update; - } - - bubbleProperties(workInProgress); - - { - if ((workInProgress.mode & ProfileMode) !== NoMode) { - if (nextDidTimeout) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var _primaryChildFragment2 = workInProgress.child; - - if (_primaryChildFragment2 !== null) { - // $FlowFixMe Flow doesn't support type casting in combination with the -= operator - workInProgress.treeBaseDuration -= - _primaryChildFragment2.treeBaseDuration; - } - } - } - } - - return null; - } - - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(current, workInProgress); - - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } - - bubbleProperties(workInProgress); - return null; - - case ContextProvider: - // Pop provider fiber - var context = workInProgress.type._context; - popProvider(context, workInProgress); - bubbleProperties(workInProgress); - return null; - - case IncompleteClassComponent: { - // Same as class component case. I put it down here so that the tags are - // sequential to ensure this switch is compiled to a jump table. - var _Component = workInProgress.type; - - if (isContextProvider(_Component)) { - popContext(workInProgress); - } - - bubbleProperties(workInProgress); - return null; - } - - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; - - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - bubbleProperties(workInProgress); - return null; - } - - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; - - if (renderedTail === null) { - // We just rendered the head. - if (!didSuspendAlready) { - // This is the first pass. We need to figure out if anything is still - // suspended in the rendered set. - // If new content unsuspended, but there's still some content that - // didn't. Then we need to do a second pass that forces everything - // to keep showing their fallbacks. - // We might be suspended if something in this render pass suspended, or - // something in the previous committed pass suspended. Otherwise, - // there's no chance so we can skip the expensive call to - // findFirstSuspended. - var cannotBeSuspended = - renderHasNotSuspendedYet() && - (current === null || (current.flags & DidCapture) === NoFlags); - - if (!cannotBeSuspended) { - var row = workInProgress.child; - - while (row !== null) { - var suspended = findFirstSuspended(row); - - if (suspended !== null) { - didSuspendAlready = true; - workInProgress.flags |= DidCapture; - cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as - // part of the second pass. In that case nothing will subscribe to - // its thenables. Instead, we'll transfer its thenables to the - // SuspenseList so that it can retry if they resolve. - // There might be multiple of these in the list but since we're - // going to wait for all of them anyway, it doesn't really matter - // which ones gets to ping. In theory we could get clever and keep - // track of how many dependencies remain but it gets tricky because - // in the meantime, we can add/remove/change items and dependencies. - // We might bail out of the loop before finding any but that - // doesn't matter since that means that the other boundaries that - // we did find already has their listeners attached. - - var newThenables = suspended.updateQueue; - - if (newThenables !== null) { - workInProgress.updateQueue = newThenables; - workInProgress.flags |= Update; - } // Rerender the whole list, but this time, we'll force fallbacks - // to stay in place. - // Reset the effect flags before doing the second pass since that's now invalid. - // Reset the child fibers to their original state. - - workInProgress.subtreeFlags = NoFlags; - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. - - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); // Don't bubble properties in this case. - - return workInProgress.child; - } - - row = row.sibling; - } - } - - if (renderState.tail !== null && now() > getRenderTargetTime()) { - // We have already passed our CPU deadline but we still have rows - // left in the tail. We'll just give up further attempts to render - // the main content and only render fallbacks. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. - - workInProgress.lanes = SomeRetryLane; - } - } else { - cutOffTailIfNeeded(renderState, false); - } // Next we're going to render the tail. - } else { - // Append the rendered row to the child list. - if (!didSuspendAlready) { - var _suspended = findFirstSuspended(renderedTail); - - if (_suspended !== null) { - workInProgress.flags |= DidCapture; - didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't - // get lost if this row ends up dropped during a second pass. - - var _newThenables = _suspended.updateQueue; - - if (_newThenables !== null) { - workInProgress.updateQueue = _newThenables; - workInProgress.flags |= Update; - } - - cutOffTailIfNeeded(renderState, true); // This might have been modified. - - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate && - !getIsHydrating() // We don't cut it if we're hydrating. - ) { - // We're done. - bubbleProperties(workInProgress); - return null; - } - } else if ( - // The time it took to render last row is greater than the remaining - // time we have to render. So rendering one more row would likely - // exceed it. - now() * 2 - renderState.renderingStartTime > - getRenderTargetTime() && - renderLanes !== OffscreenLane - ) { - // We have now passed our CPU deadline and we'll just give up further - // attempts to render the main content and only render fallbacks. - // The assumption is that this is usually faster. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. - - workInProgress.lanes = SomeRetryLane; - } - } - - if (renderState.isBackwards) { - // The effect list of the backwards tail will have been added - // to the end. This breaks the guarantee that life-cycles fire in - // sibling order but that isn't a strong guarantee promised by React. - // Especially since these might also just pop in during future commits. - // Append to the beginning of the list. - renderedTail.sibling = workInProgress.child; - workInProgress.child = renderedTail; - } else { - var previousSibling = renderState.last; - - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } - - renderState.last = renderedTail; - } - } - - if (renderState.tail !== null) { - // We still have tail rows to render. - // Pop a row. - var next = renderState.tail; - renderState.rendering = next; - renderState.tail = next.sibling; - renderState.renderingStartTime = now(); - next.sibling = null; // Restore the context. - // TODO: We can probably just avoid popping it instead and only - // setting it the first time we go from not suspended to suspended. - - var suspenseContext = suspenseStackCursor.current; - - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } - - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - // Don't bubble properties in this case. - - return next; - } - - bubbleProperties(workInProgress); - return null; - } - - case ScopeComponent: { - break; - } - - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); - var _nextState = workInProgress.memoizedState; - var nextIsHidden = _nextState !== null; - - if (current !== null) { - var _prevState2 = current.memoizedState; - var prevIsHidden = _prevState2 !== null; - - if ( - prevIsHidden !== nextIsHidden && // LegacyHidden doesn't do any hiding — it only pre-renders. - !enableLegacyHidden - ) { - workInProgress.flags |= Visibility; - } - } - - if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) { - bubbleProperties(workInProgress); - } else { - // Don't bubble properties for hidden children unless we're rendering - // at offscreen priority. - if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { - bubbleProperties(workInProgress); - - { - // Check if there was an insertion or update in the hidden subtree. - // If so, we need to hide those nodes in the commit phase, so - // schedule a visibility effect. - if (workInProgress.subtreeFlags & (Placement | Update)) { - workInProgress.flags |= Visibility; - } - } - } - } - - return null; - } - - case CacheComponent: { - return null; - } - - case TracingMarkerComponent: { - return null; - } - } - - throw new Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in " + - "React. Please file an issue." - ); -} - var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; var didReceiveUpdate = false; var didWarnAboutBadClass; @@ -14652,7 +13982,23 @@ function updateSimpleMemoComponent( current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. workInProgress.type === current.type ) { - didReceiveUpdate = false; + didReceiveUpdate = false; // The props are shallowly equal. Reuse the previous props object, like we + // would during a normal fiber bailout. + // + // We don't have strong guarantees that the props object is referentially + // equal during updates where we can't bail out anyway — like if the props + // are shallowly equal, but there's a local state or context update in the + // same batch. + // + // However, as a principle, we should aim to make the behavior consistent + // across different ways of memoizing a component. For example, React.memo + // has a different internal Fiber layout if you pass a normal function + // component (SimpleMemoComponent) versus if you pass a different type + // like forwardRef (MemoComponent). But this is an implementation detail. + // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't + // affect whether the props object is reused during a bailout. + + workInProgress.pendingProps = nextProps = prevProps; if (!checkScheduledUpdateOrContext(current, renderLanes)) { // The pending lanes were cleared at the beginning of beginWork. We're @@ -14700,9 +14046,11 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { // Rendering a hidden tree. if ((workInProgress.mode & ConcurrentMode) === NoMode) { // In legacy sync mode, don't defer the subtree. Render it now. + // TODO: Consider how Offscreen should work with transitions in the future var nextState = { baseLanes: NoLanes, - cachePool: null + cachePool: null, + transitions: null }; workInProgress.memoizedState = nextState; @@ -14725,7 +14073,8 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { ); var _nextState = { baseLanes: nextBaseLanes, - cachePool: spawnedCachePool + cachePool: spawnedCachePool, + transitions: null }; workInProgress.memoizedState = _nextState; workInProgress.updateQueue = null; @@ -14740,7 +14089,8 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { // Rendering at offscreen, so we can clear the base lanes. var _nextState2 = { baseLanes: NoLanes, - cachePool: null + cachePool: null, + transitions: null }; workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. @@ -14768,11 +14118,9 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { pushRenderLanes(workInProgress, _subtreeRenderLanes); } - { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; - } -} + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} // Note: These happen to have identical begin phases, for now. We shouldn't hold function updateFragment(current, workInProgress, renderLanes) { var nextChildren = workInProgress.pendingProps; @@ -14805,7 +14153,7 @@ function updateProfiler(current, workInProgress, renderLanes) { return workInProgress.child; } -function markRef$1(current, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( @@ -14952,16 +14300,7 @@ function updateClassComponent( var shouldUpdate; if (instance === null) { - if (current !== null) { - // A class component without an instance only mounts if it suspended - // inside a non-concurrent tree, in an inconsistent state. We want to - // treat it like a new mount, even though an empty version of it already - // committed. Disconnect the alternate pointers. - current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } // In the initial pass we might need to construct the instance. + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance. constructClassInstance(workInProgress, Component, nextProps); mountClassInstance(workInProgress, Component, nextProps, renderLanes); @@ -15021,7 +14360,7 @@ function finishClassComponent( renderLanes ) { // Refs should update even if shouldComponentUpdate returns false - markRef$1(current, workInProgress); + markRef(current, workInProgress); var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; if (!shouldUpdate && !didCaptureError) { @@ -15134,7 +14473,7 @@ function updateHostRoot(current, workInProgress, renderLanes) { return workInProgress.child; } -function updateHostComponent$1(current, workInProgress, renderLanes) { +function updateHostComponent(current, workInProgress, renderLanes) { pushHostContext(workInProgress); var type = workInProgress.type; @@ -15148,12 +14487,12 @@ function updateHostComponent$1(current, workInProgress, renderLanes) { workInProgress.flags |= ContentReset; } - markRef$1(current, workInProgress); + markRef(current, workInProgress); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function updateHostText$1(current, workInProgress) { +function updateHostText(current, workInProgress) { // immediately after. return null; @@ -15165,17 +14504,7 @@ function mountLazyComponent( elementType, renderLanes ) { - if (_current !== null) { - // A lazy component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } - + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); var props = workInProgress.pendingProps; var lazyComponent = elementType; var payload = lazyComponent._payload; @@ -15296,16 +14625,7 @@ function mountIncompleteClassComponent( nextProps, renderLanes ) { - if (_current !== null) { - // An incomplete component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` // Push context providers early to prevent context stack mismatches. @@ -15340,17 +14660,7 @@ function mountIndeterminateComponent( Component, renderLanes ) { - if (_current !== null) { - // An indeterminate component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } - + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); var props = workInProgress.pendingProps; var context; @@ -15576,7 +14886,8 @@ var SUSPENDED_MARKER = { function mountSuspenseOffscreenState(renderLanes) { return { baseLanes: renderLanes, - cachePool: getSuspendedCache() + cachePool: getSuspendedCache(), + transitions: null }; } @@ -15585,7 +14896,8 @@ function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { return { baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), - cachePool: cachePool + cachePool: cachePool, + transitions: prevOffscreenState.transitions }; } // TODO: Probably should inline this back @@ -15677,6 +14989,16 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { // a stack. if (current === null) { + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null) { + var dehydrated = suspenseState.dehydrated; + + if (dehydrated !== null) { + return mountDehydratedSuspenseComponent(workInProgress); + } + } + var nextPrimaryChildren = nextProps.children; var nextFallbackChildren = nextProps.fallback; @@ -15692,98 +15014,67 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { renderLanes ); workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackFragment; } else { return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); } } else { // This is an update. - // If the current fiber has a SuspenseState, that means it's already showing - // a fallback. + // Special path for hydration var prevState = current.memoizedState; if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; + var _dehydrated = prevState.dehydrated; - var _fallbackChildFragment = updateSuspenseFallbackChildren( + if (_dehydrated !== null) { + return updateDehydratedSuspenseComponent( current, workInProgress, - _nextPrimaryChildren2, - _nextFallbackChildren2, + didSuspend, + nextProps, + _dehydrated, + prevState, renderLanes ); - - var _primaryChildFragment3 = workInProgress.child; - var prevOffscreenState = current.child.memoizedState; - _primaryChildFragment3.memoizedState = - prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); - _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment; - } else { - var _nextPrimaryChildren3 = nextProps.children; - - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren3, - renderLanes - ); - - workInProgress.memoizedState = null; - return _primaryChildFragment4; } + } + + if (showFallback) { + var _nextFallbackChildren = nextProps.fallback; + var _nextPrimaryChildren = nextProps.children; + var fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren, + _nextFallbackChildren, + renderLanes + ); + var _primaryChildFragment2 = workInProgress.child; + var prevOffscreenState = current.child.memoizedState; + _primaryChildFragment2.memoizedState = + prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); + + _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree( + current, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; } else { - // The current tree is not already showing a fallback. - if (showFallback) { - // Timed out. - var _nextFallbackChildren3 = nextProps.fallback; - var _nextPrimaryChildren4 = nextProps.children; + var _nextPrimaryChildren2 = nextProps.children; - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes - ); + var _primaryChildFragment3 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren2, + renderLanes + ); - var _primaryChildFragment5 = workInProgress.child; - var _prevOffscreenState = current.child.memoizedState; - _primaryChildFragment5.memoizedState = - _prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes); - _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes - ); // Skip the primary children, and continue working on the - // fallback children. - - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment2; - } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - var _nextPrimaryChildren5 = nextProps.children; - - var _primaryChildFragment6 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren5, - renderLanes - ); - - workInProgress.memoizedState = null; - return _primaryChildFragment6; - } + workInProgress.memoizedState = null; + return _primaryChildFragment3; } } } @@ -15963,7 +15254,7 @@ function updateSuspenseFallbackChildren( currentPrimaryChildFragment.selfBaseDuration; primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration; - } + } // The fallback fiber was added as a deletion during the first pass. // However, since we're going to remain on the fallback, we no longer want // to delete it. @@ -15972,7 +15263,7 @@ function updateSuspenseFallbackChildren( primaryChildFragment = updateWorkInProgressOffscreenFiber( currentPrimaryChildFragment, primaryChildProps - ); + ); // Since we're reusing a current tree, we need to reuse the flags, too. // (We don't do this in legacy mode, because in legacy mode we don't re-use // the current tree; see previous branch.) @@ -16006,6 +15297,288 @@ function updateSuspenseFallbackChildren( return fallbackChildFragment; } +function retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + recoverableError +) { + // Falling back to client rendering. Because this has performance + // implications, it's considered a recoverable error, even though the user + // likely won't observe anything wrong with the UI. + // + // The error is passed in as an argument to enforce that every caller provide + // a custom message, or explicitly opt out (currently the only path that opts + // out is legacy mode; every concurrent path provides an error). + if (recoverableError !== null) { + queueHydrationError(recoverableError); + } // This will add the old fiber to the deletion list + + reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated. + + var nextProps = workInProgress.pendingProps; + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren( + workInProgress, + primaryChildren + ); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. + + primaryChildFragment.flags |= Placement; + workInProgress.memoizedState = null; + return primaryChildFragment; +} + +function mountSuspenseFallbackAfterRetryWithoutHydrating( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var fiberMode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + fiberMode + ); + var fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + fiberMode, + renderLanes, + null + ); // Needs a placement effect because the parent (the Suspense + // boundary) already mounted but this is a new fiber. + + fallbackChildFragment.flags |= Placement; + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // We will have dropped the effect list which contains the + // deletion. We need to reconcile to delete the current child. + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + } + + return fallbackChildFragment; +} + +function mountDehydratedSuspenseComponent( + workInProgress, + suspenseInstance, + renderLanes +) { + // During the first pass, we'll bail out and not drill into the children. + // Instead, we'll leave the content in place and try to hydrate it later. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + { + error( + "Cannot hydrate Suspense in legacy mode. Switch from " + + "ReactDOM.hydrate(element, container) to " + + "ReactDOMClient.hydrateRoot(container, )" + + ".render(element) or remove the Suspense components from " + + "the server rendered components." + ); + } + + workInProgress.lanes = laneToLanes(SyncLane); + } else if (isSuspenseInstanceFallback()) { + // This is a client-only boundary. Since we won't get any content from the server + // for this, we need to schedule that at a higher priority based on when it would + // have timed out. In theory we could render it in this pass but it would have the + // wrong priority associated with it and will prevent hydration of parent path. + // Instead, we'll leave work left on it to render it in a separate commit. + // TODO This time should be the time at which the server rendered response that is + // a parent to this boundary was displayed. However, since we currently don't have + // a protocol to transfer that time, we'll just estimate it by using the current + // time. This will mean that Suspense timeouts are slightly shifted to later than + // they should be. + // Schedule a normal pri update to render this content. + workInProgress.lanes = laneToLanes(DefaultHydrationLane); + } else { + // We'll continue hydrating the rest at offscreen priority since we'll already + // be showing the right content coming from the server, it is no rush. + workInProgress.lanes = laneToLanes(OffscreenLane); + } + + return null; +} + +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + nextProps, + suspenseInstance, + suspenseState, + renderLanes +) { + if (!didSuspend) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, // TODO: When we delete legacy mode, we should make this error argument + // required — every concurrent mode path that causes hydration to + // de-opt to client rendering should have an error message. + null + ); + } + + if (isSuspenseInstanceFallback()) { + // This boundary is in a permanent fallback state. In this case, we'll never + // get an update and we'll never be able to hydrate the final content. Let's just try the + // client side render instead. + var _getSuspenseInstanceF = getSuspenseInstanceFallbackErrorDetails(), + errorMessage = _getSuspenseInstanceF.errorMessage; + + var error = errorMessage // eslint-disable-next-line react-internal/prod-error-codes + ? new Error(errorMessage) + : new Error( + "The server could not finish this Suspense boundary, likely " + + "due to an error during server rendering. Switched to " + + "client rendering." + ); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + error + ); + } + // any context has changed, we need to treat is as if the input might have changed. + + var hasContextChanged = includesSomeLane(renderLanes, current.childLanes); + + if (didReceiveUpdate || hasContextChanged) { + // This boundary has changed since the first render. This means that we are now unable to + // hydrate it. We might still be able to hydrate it using a higher priority lane. + var root = getWorkInProgressRoot(); + + if (root !== null) { + var attemptHydrationAtLane = getBumpedLaneForHydration( + root, + renderLanes + ); + + if ( + attemptHydrationAtLane !== NoLane && + attemptHydrationAtLane !== suspenseState.retryLane + ) { + // Intentionally mutating since this render will get interrupted. This + // is one of the very rare times where we mutate the current tree + // during the render phase. + suspenseState.retryLane = attemptHydrationAtLane; // TODO: Ideally this would inherit the event time of the current render + + var eventTime = NoTimestamp; + scheduleUpdateOnFiber(current, attemptHydrationAtLane, eventTime); + } + } // If we have scheduled higher pri work above, this will probably just abort the render + // since we now have higher priority work, but in case it doesn't, we need to prepare to + // render something, if we time out. Even if that requires us to delete everything and + // skip hydration. + // Delay having to do this as long as the suspense timeout allows us. + + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + new Error( + "This Suspense boundary received an update before it finished " + + "hydrating. This caused the boundary to switch to client rendering. " + + "The usual way to fix this is to wrap the original update " + + "in startTransition." + ) + ); + } else if (isSuspenseInstancePending()) { + // This component is still pending more data from the server, so we can't hydrate its + // content. We treat it as if this component suspended itself. It might seem as if + // we could just try to render it client-side instead. However, this will perform a + // lot of unnecessary work and is unlikely to complete since it often will suspend + // on missing data anyway. Additionally, the server might be able to render more + // than we can on the client yet. In that case we'd end up with more fallback states + // on the client than if we just leave it alone. If the server times out or errors + // these should update this boundary to the permanent Fallback state instead. + // Mark it as having captured (i.e. suspended). + workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. + + workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result. + + var retry = retryDehydratedSuspenseBoundary.bind(null, current); + registerSuspenseInstanceRetry(); + return null; + } else { + // This is the first attempt. + reenterHydrationStateFromDehydratedSuspenseInstance( + workInProgress, + suspenseInstance, + suspenseState.treeContext + ); + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren( + workInProgress, + primaryChildren + ); // Mark the children as hydrating. This is a fast path to know whether this + // tree is part of a hydrating tree. This is used to determine if a child + // node has fully mounted yet, and for scheduling event replaying. + // Conceptually this is similar to Placement in that a new subtree is + // inserted into the React tree here. It just happens to not need DOM + // mutations because it already exists. + + primaryChildFragment.flags |= Hydrating; + return primaryChildFragment; + } + } else { + // This is the second render pass. We already attempted to hydrated, but + // something either suspended or errored. + if (workInProgress.flags & ForceClientRender) { + // Something errored during hydration. Try again without hydrating. + workInProgress.flags &= ~ForceClientRender; + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + new Error( + "There was an error while hydrating this Suspense boundary. " + + "Switched to client rendering." + ) + ); + } else if (workInProgress.memoizedState !== null) { + // Something suspended and we should still be in dehydrated mode. + // Leave the existing child in place. + workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there + // but the normal suspense pass doesn't. + + workInProgress.flags |= DidCapture; + return null; + } else { + // Suspended but we should no longer be in dehydrated mode. + // Therefore we now have to render the fallback. + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating( + current, + workInProgress, + nextPrimaryChildren, + nextFallbackChildren, + renderLanes + ); + var _primaryChildFragment4 = workInProgress.child; + _primaryChildFragment4.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; + } + } +} + function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes = mergeLanes(fiber.lanes, renderLanes); var alternate = fiber.alternate; @@ -16551,6 +16124,21 @@ function markWorkInProgressReceivedUpdate() { didReceiveUpdate = true; } +function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if (current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + + workInProgress.flags |= Placement; + } + } +} + function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { if (current !== null) { // Reuse previous dependencies @@ -16712,6 +16300,19 @@ function attemptEarlyBailoutIfNoScheduledUpdate( var state = workInProgress.memoizedState; if (state !== null) { + if (state.dehydrated !== null) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has + // been unsuspended it has committed as a resolved Suspense component. + // If it needs to be retried, it should have work scheduled on it. + + workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we + // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork. + + return null; + } // If this boundary is currently timed out, we need to decide // whether to retry the primary children, or to skip over it and // go straight to the fallback. Check the priority of the primary // child fragment. @@ -16961,10 +16562,10 @@ function beginWork(current, workInProgress, renderLanes) { return updateHostRoot(current, workInProgress, renderLanes); case HostComponent: - return updateHostComponent$1(current, workInProgress, renderLanes); + return updateHostComponent(current, workInProgress, renderLanes); case HostText: - return updateHostText$1(); + return updateHostText(); case SuspenseComponent: return updateSuspenseComponent(current, workInProgress, renderLanes); @@ -17085,6 +16686,993 @@ function beginWork(current, workInProgress, renderLanes) { ); } +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; +} + +function markRef$1(workInProgress) { + workInProgress.flags |= Ref; +} + +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; + +{ + // Mutation mode + appendAllChildren = function( + parent, + workInProgress, + needsVisibilityToggle, + isHidden + ) { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; + + while (node !== null) { + if (node.tag === HostComponent || node.tag === HostText) { + appendInitialChild(parent, node.stateNode); + } else if (node.tag === HostPortal); + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + if (node === workInProgress) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + }; + + updateHostContainer = function(current, workInProgress) { + // Noop + }; + + updateHostComponent$1 = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + // If we have an alternate, that means this is an update and we need to + // schedule a side-effect to do the updates. + var oldProps = current.memoizedProps; + + if (oldProps === newProps) { + // In mutation mode, this is sufficient for a bailout because + // we won't touch this node even if children changed. + return; + } // If we get updated because one of our children updated, we don't + // have newProps so we'll have to reuse them. + // TODO: Split the update API as separate for the props vs. children. + // Even better would be if children weren't special cased at all tho. + + var instance = workInProgress.stateNode; + var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host + // component is hitting the resume path. Figure out why. Possibly + // related to `hidden`. + + var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. + + workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there + // is a new ref we mark this as an update. All the work is done in commitWork. + + if (updatePayload) { + markUpdate(workInProgress); + } + }; + + updateHostText$1 = function(current, workInProgress, oldText, newText) { + // If the text differs, mark it as an update. All the work in done in commitWork. + if (oldText !== newText) { + markUpdate(workInProgress); + } + }; +} + +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; + + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } + + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + } + + break; + } + + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; + + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } + + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + } + + break; + } + } +} + +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; + + if (!didBailout) { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var actualDuration = completedWork.actualDuration; + var treeBaseDuration = completedWork.selfBaseDuration; + var child = completedWork.child; + + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes) + ); + subtreeFlags |= child.subtreeFlags; + subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will + // only be updated if work is done on the fiber (i.e. it doesn't bailout). + // When work is done, it should bubble to the parent's actualDuration. If + // the fiber has not been cloned though, (meaning no work was done), then + // this value will reflect the amount of time spent working on a previous + // render. In that case it should not bubble. We determine whether it was + // cloned by comparing the child pointer. + + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } + + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; + + while (_child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child.lanes, _child.childLanes) + ); + subtreeFlags |= _child.subtreeFlags; + subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child.return = completedWork; + _child = _child.sibling; + } + } + + completedWork.subtreeFlags |= subtreeFlags; + } else { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var _treeBaseDuration = completedWork.selfBaseDuration; + var _child2 = completedWork.child; + + while (_child2 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child2.lanes, _child2.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + + subtreeFlags |= _child2.subtreeFlags & StaticMask; + subtreeFlags |= _child2.flags & StaticMask; + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } + + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; + + while (_child3 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child3.lanes, _child3.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + + subtreeFlags |= _child3.subtreeFlags & StaticMask; + subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } + + completedWork.subtreeFlags |= subtreeFlags; + } + + completedWork.childLanes = newChildLanes; + return didBailout; +} + +function completeDehydratedSuspenseBoundary( + current, + workInProgress, + nextState +) { + var wasHydrated = popHydrationState(); + + if (nextState !== null && nextState.dehydrated !== null) { + // We might be inside a hydration state the first time we're picking up this + // Suspense boundary, and also after we've reentered it for further hydration. + if (current === null) { + if (!wasHydrated) { + throw new Error( + "A dehydrated suspense component was completed without a hydrated node. " + + "This is probably a bug in React." + ); + } + + prepareToHydrateHostSuspenseInstance(); + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var isTimedOutSuspense = nextState !== null; + + if (isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + + if (primaryChildFragment !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + primaryChildFragment.treeBaseDuration; + } + } + } + } + + return false; + } else { + if ((workInProgress.flags & DidCapture) === NoFlags) { + // This boundary did not suspend so it's now hydrated and unsuspended. + workInProgress.memoizedState = null; + } // If nothing suspended, we need to schedule an effect to mark this boundary + // as having hydrated so events know that they're free to be invoked. + // It's also a signal to replay events and the suspense callback. + // If something suspended, schedule an effect to attach retry listeners. + // So we might as well always mark this. + + workInProgress.flags |= Update; + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var _isTimedOutSuspense = nextState !== null; + + if (_isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var _primaryChildFragment = workInProgress.child; + + if (_primaryChildFragment !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment.treeBaseDuration; + } + } + } + } + + return false; + } + } else { + // Successfully completed this tree. If this was a forced client render, + // there may have been recoverable errors during first hydration + // attempt. If so, add them to a queue so we can log them in the + // commit phase. + upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path + + return true; + } +} + +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing + // to the current tree provider fiber is just as fast and less error-prone. + // Ideally we would have a special version of the work loop only + // for hydration. + + popTreeContext(workInProgress); + + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); + return null; + + case ClassComponent: { + var Component = workInProgress.type; + + if (isContextProvider(Component)) { + popContext(workInProgress); + } + + bubbleProperties(workInProgress); + return null; + } + + case HostRoot: { + var fiberRoot = workInProgress.stateNode; + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); + + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } + + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(); + + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + } else { + if (current !== null) { + var prevState = current.memoizedState; + + if ( + // Check if this is a client root + !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error) + (workInProgress.flags & ForceClientRender) !== NoFlags + ) { + // Schedule an effect to clear this container at the start of the + // next commit. This handles the case of React rendering into a + // container with previous children. It's also safe to do for + // updates too, because current.child would only be null if the + // previous render was null (so the container would already + // be empty). + workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been + // recoverable errors during first hydration attempt. If so, add + // them to a queue so we can log them in the commit phase. + + upgradeHydrationErrorsToRecoverable(); + } + } + } + } + + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + + return null; + } + + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); + + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } + } else { + if (!newProps) { + if (workInProgress.stateNode === null) { + throw new Error( + "We must have new props for new mounts. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + + bubbleProperties(workInProgress); + return null; + } + + var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context + // "stack" as the parent. Then append children as we go in beginWork + // or completeWork depending on whether we want to add them top->down or + // bottom->up. Top->down is faster in IE11. + + var _wasHydrated = popHydrationState(); + + if (_wasHydrated) { + // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + if (prepareToHydrateHostInstance()) { + // If changes to the hydrated node need to be applied at the + // commit-phase we mark this as such. + markUpdate(workInProgress); + } + } else { + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress + ); + appendAllChildren(instance, workInProgress, false, false); + workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. + // (eg DOM renderer supports auto-focus for certain elements). + // Make sure such renderers get scheduled for later work. + + if (finalizeInitialChildren(instance)) { + markUpdate(workInProgress); + } + } + + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + } + + bubbleProperties(workInProgress); + return null; + } + + case HostText: { + var newText = newProps; + + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. + + updateHostText$1(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (workInProgress.stateNode === null) { + throw new Error( + "We must have new props for new mounts. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + } + + var _rootContainerInstance = getRootHostContainer(); + + var _currentHostContext = getHostContext(); + + var _wasHydrated2 = popHydrationState(); + + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } + } + + bubbleProperties(workInProgress); + return null; + } + + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this + // to its own fiber type so that we can add other kinds of hydration + // boundaries that aren't associated with a Suspense tree. In anticipation + // of such a refactor, all the hydration logic is contained in + // this branch. + + if ( + current === null || + (current.memoizedState !== null && + current.memoizedState.dehydrated !== null) + ) { + var fallthroughToNormalSuspensePath = completeDehydratedSuspenseBoundary( + current, + workInProgress, + nextState + ); + + if (!fallthroughToNormalSuspensePath) { + if (workInProgress.flags & ShouldCapture) { + // Special case. There were remaining unhydrated nodes. We treat + // this as a mismatch. Revert to client rendering. + return workInProgress; + } else { + // Did not finish hydrating, either because this is the initial + // render or because something suspended. + return null; + } + } // Continue with the normal Suspense path. + } + + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. + + return workInProgress; + } + + var nextDidTimeout = nextState !== null; + var prevDidTimeout = current !== null && current.memoizedState !== null; + // a passive effect, which is when we process the transitions + + if (nextDidTimeout !== prevDidTimeout) { + // an effect to toggle the subtree's visibility. When we switch from + // fallback -> primary, the inner Offscreen fiber schedules this effect + // as part of its normal complete phase. But when we switch from + // primary -> fallback, the inner Offscreen fiber does not have a complete + // phase. So we need to schedule its effect here. + // + // We also use this flag to connect/disconnect the effects, but the same + // logic applies: when re-connecting, the Offscreen fiber's complete + // phase will handle scheduling the effect. It's only when the fallback + // is active that we have to do anything special. + + if (nextDidTimeout) { + var _offscreenFiber2 = workInProgress.child; + _offscreenFiber2.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything + // in the concurrent tree already suspended during this render. + // This is a known bug. + + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // TODO: Move this back to throwException because this is too late + // if this is a large tree which is common for initial loads. We + // don't know if we should restart a render or not until we get + // this marker, and this is too late. + // If this render already had a ping or lower pri updates, + // and this is the first time we know we're going to suspend we + // should be able to immediately restart from within throwException. + var hasInvisibleChildContext = + current === null && + (workInProgress.memoizedProps.unstable_avoidThisFallback !== + true || + !enableSuspenseAvoidThisFallback); + + if ( + hasInvisibleChildContext || + hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ) + ) { + // If this was in an invisible tree or a new render, then showing + // this boundary is ok. + renderDidSuspend(); + } else { + // Otherwise, we're going to have to hide content so we should + // suspend for longer if possible. + renderDidSuspendDelayIfPossible(); + } + } + } + } + + var wakeables = workInProgress.updateQueue; + + if (wakeables !== null) { + // Schedule an effect to attach a retry listener to the promise. + // TODO: Move to passive phase + workInProgress.flags |= Update; + } + + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + + if (primaryChildFragment !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + primaryChildFragment.treeBaseDuration; + } + } + } + } + + return null; + } + + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); + + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); + } + + bubbleProperties(workInProgress); + return null; + + case ContextProvider: + // Pop provider fiber + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; + + case IncompleteClassComponent: { + // Same as class component case. I put it down here so that the tags are + // sequential to ensure this switch is compiled to a jump table. + var _Component = workInProgress.type; + + if (isContextProvider(_Component)) { + popContext(workInProgress); + } + + bubbleProperties(workInProgress); + return null; + } + + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } + + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; + + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || (current.flags & DidCapture) === NoFlags); + + if (!cannotBeSuspended) { + var row = workInProgress.child; + + while (row !== null) { + var suspended = findFirstSuspended(row); + + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.flags |= DidCapture; + cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as + // part of the second pass. In that case nothing will subscribe to + // its thenables. Instead, we'll transfer its thenables to the + // SuspenseList so that it can retry if they resolve. + // There might be multiple of these in the list but since we're + // going to wait for all of them anyway, it doesn't really matter + // which ones gets to ping. In theory we could get clever and keep + // track of how many dependencies remain but it gets tricky because + // in the meantime, we can add/remove/change items and dependencies. + // We might bail out of the loop before finding any but that + // doesn't matter since that means that the other boundaries that + // we did find already has their listeners attached. + + var newThenables = suspended.updateQueue; + + if (newThenables !== null) { + workInProgress.updateQueue = newThenables; + workInProgress.flags |= Update; + } // Rerender the whole list, but this time, we'll force fallbacks + // to stay in place. + // Reset the effect flags before doing the second pass since that's now invalid. + // Reset the child fibers to their original state. + + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. + + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. + + return workInProgress.child; + } + + row = row.sibling; + } + } + + if (renderState.tail !== null && now() > getRenderTargetTime()) { + // We have already passed our CPU deadline but we still have rows + // left in the tail. We'll just give up further attempts to render + // the main content and only render fallbacks. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + + workInProgress.lanes = SomeRetryLane; + } + } else { + cutOffTailIfNeeded(renderState, false); + } // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); + + if (_suspended !== null) { + workInProgress.flags |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. + + var _newThenables = _suspended.updateQueue; + + if (_newThenables !== null) { + workInProgress.updateQueue = _newThenables; + workInProgress.flags |= Update; + } + + cutOffTailIfNeeded(renderState, true); // This might have been modified. + + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate && + !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We're done. + bubbleProperties(workInProgress); + return null; + } + } else if ( + // The time it took to render last row is greater than the remaining + // time we have to render. So rendering one more row would likely + // exceed it. + now() * 2 - renderState.renderingStartTime > + getRenderTargetTime() && + renderLanes !== OffscreenLane + ) { + // We have now passed our CPU deadline and we'll just give up further + // attempts to render the main content and only render fallbacks. + // The assumption is that this is usually faster. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + + workInProgress.lanes = SomeRetryLane; + } + } + + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; + + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } + + renderState.last = renderedTail; + } + } + + if (renderState.tail !== null) { + // We still have tail rows to render. + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.renderingStartTime = now(); + next.sibling = null; // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + + var suspenseContext = suspenseStackCursor.current; + + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } + + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. + + return next; + } + + bubbleProperties(workInProgress); + return null; + } + + case ScopeComponent: { + break; + } + + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; + + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; + + if ( + prevIsHidden !== nextIsHidden && // LegacyHidden doesn't do any hiding — it only pre-renders. + !enableLegacyHidden + ) { + workInProgress.flags |= Visibility; + } + } + + if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) { + bubbleProperties(workInProgress); + } else { + // Don't bubble properties for hidden children unless we're rendering + // at offscreen priority. + if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { + bubbleProperties(workInProgress); + + { + // Check if there was an insertion or update in the hidden subtree. + // If so, we need to hide those nodes in the commit phase, so + // schedule a visibility effect. + if (workInProgress.subtreeFlags & (Placement | Update)) { + workInProgress.flags |= Visibility; + } + } + } + } + return null; + } + + case CacheComponent: { + return null; + } + + case TracingMarkerComponent: { + return null; + } + } + + throw new Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in " + + "React. Please file an issue." + ); +} + function unwindWork(current, workInProgress, renderLanes) { // Note: This intentionally doesn't check if we're hydrating because comparing // to the current tree provider fiber is just as fast and less error-prone. @@ -17116,6 +17704,7 @@ function unwindWork(current, workInProgress, renderLanes) { } case HostRoot: { + var root = workInProgress.stateNode; popHostContainer(workInProgress); popTopLevelContextObject(workInProgress); resetWorkInProgressVersions(); @@ -17142,6 +17731,16 @@ function unwindWork(current, workInProgress, renderLanes) { case SuspenseComponent: { popSuspenseContext(workInProgress); + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null && suspenseState.dehydrated !== null) { + if (workInProgress.alternate === null) { + throw new Error( + "Threw in newly mounted dehydrated component. This is likely a bug in " + + "React. Please file an issue." + ); + } + } var _flags2 = workInProgress.flags; @@ -17177,7 +17776,6 @@ function unwindWork(current, workInProgress, renderLanes) { case OffscreenComponent: case LegacyHiddenComponent: popRenderLanes(workInProgress); - return null; case CacheComponent: @@ -17207,6 +17805,7 @@ function unwindInterruptedWork(current, interruptedWork, renderLanes) { } case HostRoot: { + var root = interruptedWork.stateNode; popHostContainer(interruptedWork); popTopLevelContextObject(interruptedWork); resetWorkInProgressVersions(); @@ -17238,7 +17837,6 @@ function unwindInterruptedWork(current, interruptedWork, renderLanes) { case OffscreenComponent: case LegacyHiddenComponent: popRenderLanes(interruptedWork); - break; } } @@ -17253,7 +17851,6 @@ var nextEffect = null; // Used for Profiling builds to track updaters. var inProgressLanes = null; var inProgressRoot = null; - function reportUncaughtErrorInDEV(error) { // Wrapping each small part of the commit phase into a guarded // callback is a bit too slow (https://github.com/facebook/react/pull/21666). @@ -17292,7 +17889,6 @@ function safelyCallComponentWillUnmount( try { callComponentWillUnmountWithTimer(current, instance); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(current, nearestMountedAncestor, error); } } // Capture errors so they don't interrupt mounting. @@ -17320,7 +17916,6 @@ function safelyDetachRef(current, nearestMountedAncestor) { retVal = ref(null); } } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(current, nearestMountedAncestor, error); } @@ -17343,7 +17938,6 @@ function safelyCallDestroy(current, nearestMountedAncestor, destroy) { try { destroy(); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(current, nearestMountedAncestor, error); } } @@ -17371,7 +17965,7 @@ function commitBeforeMutationEffects_begin() { (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null ) { - ensureCorrectReturnPointer(child, fiber); + child.return = fiber; nextEffect = child; } else { commitBeforeMutationEffects_complete(); @@ -17387,7 +17981,6 @@ function commitBeforeMutationEffects_complete() { try { commitBeforeMutationEffectsOnFiber(fiber); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(fiber, fiber.return, error); } @@ -17395,7 +17988,7 @@ function commitBeforeMutationEffects_complete() { var sibling = fiber.sibling; if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); + sibling.return = fiber.return; nextEffect = sibling; return; } @@ -17529,7 +18122,19 @@ function commitHookEffectListUnmount( effect.destroy = undefined; if (destroy !== undefined) { + { + if ((flags & Insertion) !== NoFlags$1) { + setIsRunningInsertionEffect(true); + } + } + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + + { + if ((flags & Insertion) !== NoFlags$1) { + setIsRunningInsertionEffect(false); + } + } } } @@ -17549,8 +18154,21 @@ function commitHookEffectListMount(flags, finishedWork) { do { if ((effect.tag & flags) === flags) { var create = effect.create; + + { + if ((flags & Insertion) !== NoFlags$1) { + setIsRunningInsertionEffect(true); + } + } + effect.destroy = create(); + { + if ((flags & Insertion) !== NoFlags$1) { + setIsRunningInsertionEffect(false); + } + } + { var destroy = effect.destroy; @@ -17964,7 +18582,8 @@ function commitLayoutEffectOnFiber( case IncompleteClassComponent: case ScopeComponent: case OffscreenComponent: - case LegacyHiddenComponent: { + case LegacyHiddenComponent: + case TracingMarkerComponent: { break; } @@ -17998,22 +18617,31 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { if (node.tag === HostComponent) { if (hostSubtreeRoot === null) { hostSubtreeRoot = node; - var instance = node.stateNode; - if (isHidden) { - hideInstance(instance); - } else { - unhideInstance(node.stateNode, node.memoizedProps); + try { + var instance = node.stateNode; + + if (isHidden) { + hideInstance(instance); + } else { + unhideInstance(node.stateNode, node.memoizedProps); + } + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); } } } else if (node.tag === HostText) { if (hostSubtreeRoot === null) { - var _instance3 = node.stateNode; + try { + var _instance3 = node.stateNode; - if (isHidden) { - hideTextInstance(); - } else { - unhideTextInstance(_instance3, node.memoizedProps); + if (isHidden) { + hideTextInstance(_instance3); + } else { + unhideTextInstance(_instance3, node.memoizedProps); + } + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); } } } else if ( @@ -18109,153 +18737,6 @@ function commitAttachRef(finishedWork) { } } -function commitDetachRef(current) { - var currentRef = current.ref; - - if (currentRef !== null) { - if (typeof currentRef === "function") { - if (current.mode & ProfileMode) { - try { - startLayoutEffectTimer(); - currentRef(null); - } finally { - recordLayoutEffectDuration(current); - } - } else { - currentRef(null); - } - } else { - currentRef.current = null; - } - } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay - -function commitUnmount(finishedRoot, current, nearestMountedAncestor) { - onCommitUnmount(current); - - switch (current.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - var updateQueue = current.updateQueue; - - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; - - do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; - - if (destroy !== undefined) { - if ((tag & Insertion) !== NoFlags$1) { - safelyCallDestroy(current, nearestMountedAncestor, destroy); - } else if ((tag & Layout) !== NoFlags$1) { - if (current.mode & ProfileMode) { - startLayoutEffectTimer(); - safelyCallDestroy(current, nearestMountedAncestor, destroy); - recordLayoutEffectDuration(current); - } else { - safelyCallDestroy(current, nearestMountedAncestor, destroy); - } - } - } - - effect = effect.next; - } while (effect !== firstEffect); - } - } - - return; - } - - case ClassComponent: { - safelyDetachRef(current, nearestMountedAncestor); - var instance = current.stateNode; - - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount( - current, - nearestMountedAncestor, - instance - ); - } - - return; - } - - case HostComponent: { - safelyDetachRef(current, nearestMountedAncestor); - return; - } - - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - unmountHostComponents(finishedRoot, current, nearestMountedAncestor); - } - - return; - } - - case DehydratedFragment: { - return; - } - - case ScopeComponent: { - return; - } - } -} - -function commitNestedUnmounts(finishedRoot, root, nearestMountedAncestor) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; - - while (true) { - commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. - - if ( - node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. - // If we don't use mutation we drill down into portals here instead. - node.tag !== HostPortal - ) { - node.child.return = node; - node = node.child; - continue; - } - - if (node === root) { - return; - } - - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } - - node = node.return; - } - - node.sibling.return = node.return; - node = node.sibling; - } -} - function detachFiberMutation(fiber) { // Cut off the return pointer to disconnect it from the tree. // This enables us to detect and warn against state updates on an unmounted component. @@ -18505,231 +18986,282 @@ function insertOrAppendPlacementNode(node, before, parent) { } } } +} // These are tracked on the stack as we recursively traverse a +// deleted subtree. +// TODO: Update these during the whole mutation phase, not just during +// a deletion. + +var hostParent = null; +var hostParentIsContainer = false; + +function commitDeletionEffects(root, returnFiber, deletedFiber) { + { + // We only have the top Fiber that was deleted but we need to recurse down its + // children to find all the terminal nodes. + // Recursively delete all host nodes from the parent, detach refs, clean + // up mounted layout effects, and call componentWillUnmount. + // We only need to remove the topmost host child in each branch. But then we + // still need to keep traversing to unmount effects, refs, and cWU. TODO: We + // could split this into two separate traversals functions, where the second + // one doesn't include any removeChild logic. This is maybe the same + // function as "disappearLayoutEffects" (or whatever that turns into after + // the layout phase is refactored to use recursion). + // Before starting, find the nearest host parent on the stack so we know + // which instance/container to remove the children from. + // TODO: Instead of searching up the fiber return path on every deletion, we + // can track the nearest host component on the JS stack as we traverse the + // tree during the commit phase. This would make insertions faster, too. + var parent = returnFiber; + + findParent: while (parent !== null) { + switch (parent.tag) { + case HostComponent: { + hostParent = parent.stateNode; + hostParentIsContainer = false; + break findParent; + } + + case HostRoot: { + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = true; + break findParent; + } + + case HostPortal: { + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = true; + break findParent; + } + } + + parent = parent.return; + } + + if (hostParent === null) { + throw new Error( + "Expected to find a host parent. This error is likely caused by " + + "a bug in React. Please file an issue." + ); + } + + commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber); + hostParent = null; + hostParentIsContainer = false; + } + + detachFiberMutation(deletedFiber); } -function unmountHostComponents(finishedRoot, current, nearestMountedAncestor) { - // We only have the top Fiber that was deleted but we need to recurse down its - // children to find all the terminal nodes. - var node = current; // Each iteration, currentParent is populated with node's host parent if not - // currentParentIsValid. +function recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + parent +) { + // TODO: Use a static flag to skip trees that don't have unmount effects + var child = parent.child; - var currentParentIsValid = false; // Note: these two variables *must* always be updated together. + while (child !== null) { + commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child); + child = child.sibling; + } +} - var currentParent; - var currentParentIsContainer; +function commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + deletedFiber +) { + onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse + // into their subtree. There are simpler cases in the inner switch + // that don't modify the stack. - while (true) { - if (!currentParentIsValid) { - var parent = node.return; - - findParent: while (true) { - if (parent === null) { - throw new Error( - "Expected to find a host parent. This error is likely caused by " + - "a bug in React. Please file an issue." - ); - } - - var parentStateNode = parent.stateNode; - - switch (parent.tag) { - case HostComponent: - currentParent = parentStateNode; - currentParentIsContainer = false; - break findParent; - - case HostRoot: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; - - case HostPortal: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; - } - - parent = parent.return; - } - - currentParentIsValid = true; + switch (deletedFiber.tag) { + case HostComponent: { + { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + } // Intentional fallthrough to next branch } + // eslint-disable-next-line-no-fallthrough - if (node.tag === HostComponent || node.tag === HostText) { - commitNestedUnmounts(finishedRoot, node, nearestMountedAncestor); // After all the children have unmounted, it is now safe to remove the - // node from the tree. + case HostText: { + // We only need to remove the nearest host child. Set the host parent + // to `null` on the stack to indicate that nested children don't + // need to be removed. + { + var prevHostParent = hostParent; + var prevHostParentIsContainer = hostParentIsContainer; + hostParent = null; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + hostParent = prevHostParent; + hostParentIsContainer = prevHostParentIsContainer; - if (currentParentIsContainer) { - removeChildFromContainer(currentParent, node.stateNode); - } else { - removeChild(currentParent, node.stateNode); - } // Don't visit children because we already visited them. - } else if (node.tag === HostPortal) { - if (node.child !== null) { - // When we go into a portal, it becomes the parent to remove from. - // We will reassign it back when we pop the portal on the way up. - currentParent = node.stateNode.containerInfo; - currentParentIsContainer = true; // Visit children because portals might contain host components. - - node.child.return = node; - node = node.child; - continue; + if (hostParent !== null) { + // Now that all the child effects have unmounted, we can remove the + // node from the tree. + if (hostParentIsContainer) { + removeChildFromContainer(hostParent, deletedFiber.stateNode); + } else { + removeChild(hostParent, deletedFiber.stateNode); + } + } } - } else { - commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below. - if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - } - - if (node === current) { return; } - while (node.sibling === null) { - if (node.return === null || node.return === current) { - return; + case DehydratedFragment: { + // Delete the dehydrated suspense boundary and all of its content. + + { + if (hostParent !== null) { + if (hostParentIsContainer) { + clearSuspenseBoundaryFromContainer( + hostParent, + deletedFiber.stateNode + ); + } else { + clearSuspenseBoundary(hostParent, deletedFiber.stateNode); + } + } } - node = node.return; - - if (node.tag === HostPortal) { - // When we go out of the portal, we need to restore the parent. - // Since we don't keep a stack of them, we will search for it. - currentParentIsValid = false; - } + return; } - node.sibling.return = node.return; - node = node.sibling; - } -} + case HostPortal: { + { + // When we go into a portal, it becomes the parent to remove from. + var _prevHostParent = hostParent; + var _prevHostParentIsContainer = hostParentIsContainer; + hostParent = deletedFiber.stateNode.containerInfo; + hostParentIsContainer = true; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + hostParent = _prevHostParent; + hostParentIsContainer = _prevHostParentIsContainer; + } -function commitDeletion(finishedRoot, current, nearestMountedAncestor) { - { - // Recursively delete all host nodes from the parent. - // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents(finishedRoot, current, nearestMountedAncestor); - } + return; + } - detachFiberMutation(current); -} - -function commitWork(current, finishedWork) { - switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: case SimpleMemoComponent: { - commitHookEffectListUnmount( - Insertion | HasEffect, - finishedWork, - finishedWork.return - ); - commitHookEffectListMount(Insertion | HasEffect, finishedWork); // Layout effects are destroyed during the mutation phase so that all - // destroy functions for all fibers are called before any create functions. - // This prevents sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. + { + var updateQueue = deletedFiber.updateQueue; - if (finishedWork.mode & ProfileMode) { - try { - startLayoutEffectTimer(); - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); - } finally { - recordLayoutEffectDuration(finishedWork); + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + + if (destroy !== undefined) { + if ((tag & Insertion) !== NoFlags$1) { + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + } else if ((tag & Layout) !== NoFlags$1) { + if (deletedFiber.mode & ProfileMode) { + startLayoutEffectTimer(); + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + recordLayoutEffectDuration(deletedFiber); + } else { + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ); + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } } - } else { - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); } + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); return; } case ClassComponent: { - return; - } + { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + var instance = deletedFiber.stateNode; - case HostComponent: { - var instance = finishedWork.stateNode; - - if (instance != null) { - // Commit the work prepared earlier. - var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. - - var oldProps = current !== null ? current.memoizedProps : newProps; - var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. - - var updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; - - if (updatePayload !== null) { - commitUpdate(instance, updatePayload, type, oldProps, newProps); + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + deletedFiber, + nearestMountedAncestor, + instance + ); } } + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); return; } - case HostText: { - if (finishedWork.stateNode === null) { - throw new Error( - "This should have a text node initialized. This error is likely " + - "caused by a bug in React. Please file an issue." + case ScopeComponent: { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + return; + } + + case OffscreenComponent: { + { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber ); } - var textInstance = finishedWork.stateNode; - var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. - - var oldText = current !== null ? current.memoizedProps : newText; - commitTextUpdate(textInstance, oldText, newText); - return; + break; } - case HostRoot: { - return; - } - - case Profiler: { - return; - } - - case SuspenseComponent: { - commitSuspenseCallback(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; - } - - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } - - case IncompleteClassComponent: { + default: { + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); return; } } - - throw new Error( - "This unit of work tag should not have side-effects. This error is " + - "likely caused by a bug in React. Please file an issue." - ); } function commitSuspenseCallback(finishedWork) { @@ -18776,122 +19308,280 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } // This function detects when a Suspense boundary goes from visible to hidden. - -function commitResetTextContent(current) { - resetTextContent(current.stateNode); -} - -function commitMutationEffects(root, firstChild, committedLanes) { +function commitMutationEffects(root, finishedWork, committedLanes) { inProgressLanes = committedLanes; inProgressRoot = root; - nextEffect = firstChild; - commitMutationEffects_begin(root, committedLanes); + setCurrentFiber(finishedWork); + commitMutationEffectsOnFiber(finishedWork, root); + setCurrentFiber(finishedWork); inProgressLanes = null; inProgressRoot = null; } -function commitMutationEffects_begin(root, lanes) { - while (nextEffect !== null) { - var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization +function recursivelyTraverseMutationEffects(root, parentFiber, lanes) { + // Deletions effects can be scheduled on any fiber type. They need to happen + // before the children effects hae fired. + var deletions = parentFiber.deletions; - var deletions = fiber.deletions; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; - if (deletions !== null) { - for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; - - try { - commitDeletion(root, childToDelete, fiber); - } catch (error) { - reportUncaughtErrorInDEV(error); - captureCommitPhaseError(childToDelete, fiber, error); - } + try { + commitDeletionEffects(root, parentFiber, childToDelete); + } catch (error) { + captureCommitPhaseError(childToDelete, parentFiber, error); } } + } - var child = fiber.child; + var prevDebugFiber = getCurrentFiber(); - if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitMutationEffects_complete(root, lanes); + if (parentFiber.subtreeFlags & MutationMask) { + var child = parentFiber.child; + + while (child !== null) { + setCurrentFiber(child); + commitMutationEffectsOnFiber(child, root); + child = child.sibling; } } -} -function commitMutationEffects_complete(root, lanes) { - while (nextEffect !== null) { - var fiber = nextEffect; - setCurrentFiber(fiber); - - try { - commitMutationEffectsOnFiber(fiber, root, lanes); - } catch (error) { - reportUncaughtErrorInDEV(error); - captureCommitPhaseError(fiber, fiber.return, error); - } - - resetCurrentFiber(); - var sibling = fiber.sibling; - - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; - return; - } - - nextEffect = fiber.return; - } + setCurrentFiber(prevDebugFiber); } function commitMutationEffectsOnFiber(finishedWork, root, lanes) { - // TODO: The factoring of this phase could probably be improved. Consider - // switching on the type of work before checking the flags. That's what - // we do in all the other phases. I think this one is only different - // because of the shared reconciliation logic below. - var flags = finishedWork.flags; + var current = finishedWork.alternate; + var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber, + // because the fiber tag is more specific. An exception is any flag related + // to reconcilation, because those can be set on all fiber types. - if (flags & ContentReset) { - commitResetTextContent(finishedWork); - } + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); - if (flags & Ref) { - var current = finishedWork.alternate; + if (flags & Update) { + try { + commitHookEffectListUnmount( + Insertion | HasEffect, + finishedWork, + finishedWork.return + ); + commitHookEffectListMount(Insertion | HasEffect, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. - if (current !== null) { - commitDetachRef(current); + if (finishedWork.mode & ProfileMode) { + try { + startLayoutEffectTimer(); + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + recordLayoutEffectDuration(finishedWork); + } else { + try { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + return; } - } - if (flags & Visibility) { - switch (finishedWork.tag) { - case SuspenseComponent: { - var newState = finishedWork.memoizedState; + case ClassComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + return; + } + + case HostComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Ref) { + if (current !== null) { + safelyDetachRef(current, current.return); + } + } + + { + // TODO: ContentReset gets cleared by the children during the commit + // phase. This is a refactor hazard because it means we must read + // flags the flags after `commitReconciliationEffects` has already run; + // the order matters. We should refactor so that ContentReset does not + // rely on mutating the flag during commit. Like by setting a flag + // during the render phase instead. + if (finishedWork.flags & ContentReset) { + var instance = finishedWork.stateNode; + + try { + resetTextContent(instance); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + + if (flags & Update) { + var _instance4 = finishedWork.stateNode; + + if (_instance4 != null) { + // Commit the work prepared earlier. + var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. + + var oldProps = current !== null ? current.memoizedProps : newProps; + var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + + var updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; + + if (updatePayload !== null) { + try { + commitUpdate( + _instance4, + updatePayload, + type, + oldProps, + newProps, + finishedWork + ); + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } + } + } + + return; + } + + case HostText: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + if (flags & Update) { + { + if (finishedWork.stateNode === null) { + throw new Error( + "This should have a text node initialized. This error is likely " + + "caused by a bug in React. Please file an issue." + ); + } + + var textInstance = finishedWork.stateNode; + var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. + + var oldText = current !== null ? current.memoizedProps : newText; + + try { + commitTextUpdate(textInstance, oldText, newText); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + + return; + } + + case HostRoot: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + return; + } + + case HostPortal: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + + return; + } + + case SuspenseComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + var offscreenFiber = finishedWork.child; + + if (offscreenFiber.flags & Visibility) { + var newState = offscreenFiber.memoizedState; var isHidden = newState !== null; if (isHidden) { - var _current = finishedWork.alternate; - var wasHidden = _current !== null && _current.memoizedState !== null; + var wasHidden = + offscreenFiber.alternate !== null && + offscreenFiber.alternate.memoizedState !== null; if (!wasHidden) { // TODO: Move to passive phase markCommitTimeOfFallback(); } } - - break; } - case OffscreenComponent: { + if (flags & Update) { + try { + commitSuspenseCallback(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + + attachSuspenseRetryListeners(finishedWork); + } + + return; + } + + case OffscreenComponent: { + var _wasHidden = current !== null && current.memoizedState !== null; + + { + recursivelyTraverseMutationEffects(root, finishedWork); + } + + commitReconciliationEffects(finishedWork); + + if (flags & Visibility) { var _newState = finishedWork.memoizedState; var _isHidden = _newState !== null; - var _current2 = finishedWork.alternate; - - var _wasHidden = _current2 !== null && _current2.memoizedState !== null; - var offscreenBoundary = finishedWork; { @@ -18900,55 +19590,54 @@ function commitMutationEffectsOnFiber(finishedWork, root, lanes) { hideOrUnhideAllChildren(offscreenBoundary, _isHidden); } } - } - } // The following switch statement is only concerned about placement, - // updates, and deletions. To avoid needing to add a case for every possible - // bitmap value, we remove the secondary effects from the effect tag and - // switch on that value. - var primaryFlags = flags & (Placement | Update | Hydrating); - - switch (primaryFlags) { - case Placement: { - commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is - // inserted, before any life-cycles like componentDidMount gets called. - // TODO: findDOMNode doesn't rely on this any more but isMounted does - // and isMounted is deprecated anyway so we should be able to kill this. - - finishedWork.flags &= ~Placement; - break; + return; } - case PlacementAndUpdate: { - // Placement - commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is - // inserted, before any life-cycles like componentDidMount gets called. + case SuspenseListComponent: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); - finishedWork.flags &= ~Placement; // Update + if (flags & Update) { + attachSuspenseRetryListeners(finishedWork); + } - var _current3 = finishedWork.alternate; - commitWork(_current3, finishedWork); - break; + return; } - case Hydrating: { - finishedWork.flags &= ~Hydrating; - break; + case ScopeComponent: { + return; } - case HydratingAndUpdate: { - finishedWork.flags &= ~Hydrating; // Update - - var _current4 = finishedWork.alternate; - commitWork(_current4, finishedWork); - break; + default: { + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + return; } + } +} - case Update: { - var _current5 = finishedWork.alternate; - commitWork(_current5, finishedWork); - break; - } +function commitReconciliationEffects(finishedWork) { + // Placement effects (insertions, reorders) can be scheduled on any fiber + // type. They needs to happen after the children effects have fired, but + // before the effects on this fiber have fired. + var flags = finishedWork.flags; + + if (flags & Placement) { + try { + commitPlacement(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. + + finishedWork.flags &= ~Placement; + } + + if (flags & Hydrating) { + finishedWork.flags &= ~Hydrating; } } @@ -18970,7 +19659,7 @@ function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { var firstChild = fiber.child; if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { - ensureCorrectReturnPointer(firstChild, fiber); + firstChild.return = fiber; nextEffect = firstChild; } else { commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); @@ -18989,7 +19678,6 @@ function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { try { commitLayoutEffectOnFiber(root, current, fiber, committedLanes); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(fiber, fiber.return, error); } @@ -19004,7 +19692,7 @@ function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { var sibling = fiber.sibling; if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); + sibling.return = fiber.return; nextEffect = sibling; return; } @@ -19013,26 +19701,51 @@ function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { } } -function commitPassiveMountEffects(root, finishedWork) { +function commitPassiveMountEffects( + root, + finishedWork, + committedLanes, + committedTransitions +) { nextEffect = finishedWork; - commitPassiveMountEffects_begin(finishedWork, root); + commitPassiveMountEffects_begin( + finishedWork, + root, + committedLanes, + committedTransitions + ); } -function commitPassiveMountEffects_begin(subtreeRoot, root) { +function commitPassiveMountEffects_begin( + subtreeRoot, + root, + committedLanes, + committedTransitions +) { while (nextEffect !== null) { var fiber = nextEffect; var firstChild = fiber.child; if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { - ensureCorrectReturnPointer(firstChild, fiber); + firstChild.return = fiber; nextEffect = firstChild; } else { - commitPassiveMountEffects_complete(subtreeRoot, root); + commitPassiveMountEffects_complete( + subtreeRoot, + root, + committedLanes, + committedTransitions + ); } } } -function commitPassiveMountEffects_complete(subtreeRoot, root) { +function commitPassiveMountEffects_complete( + subtreeRoot, + root, + committedLanes, + committedTransitions +) { while (nextEffect !== null) { var fiber = nextEffect; @@ -19040,9 +19753,13 @@ function commitPassiveMountEffects_complete(subtreeRoot, root) { setCurrentFiber(fiber); try { - commitPassiveMountOnFiber(root, fiber); + commitPassiveMountOnFiber( + root, + fiber, + committedLanes, + committedTransitions + ); } catch (error) { - reportUncaughtErrorInDEV(error); captureCommitPhaseError(fiber, fiber.return, error); } @@ -19057,7 +19774,7 @@ function commitPassiveMountEffects_complete(subtreeRoot, root) { var sibling = fiber.sibling; if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); + sibling.return = fiber.return; nextEffect = sibling; return; } @@ -19066,7 +19783,12 @@ function commitPassiveMountEffects_complete(subtreeRoot, root) { } } -function commitPassiveMountOnFiber(finishedRoot, finishedWork) { +function commitPassiveMountOnFiber( + finishedRoot, + finishedWork, + committedLanes, + committedTransitions +) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: @@ -19145,7 +19867,7 @@ function commitPassiveUnmountEffects_begin() { } if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { - ensureCorrectReturnPointer(child, fiber); + child.return = fiber; nextEffect = child; } else { commitPassiveUnmountEffects_complete(); @@ -19166,7 +19888,7 @@ function commitPassiveUnmountEffects_complete() { var sibling = fiber.sibling; if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); + sibling.return = fiber.return; nextEffect = sibling; return; } @@ -19216,7 +19938,7 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( // do this, still need to handle `deletedTreeCleanUpLevel` correctly.) if (child !== null) { - ensureCorrectReturnPointer(child, fiber); + child.return = fiber; nextEffect = child; } else { commitPassiveUnmountEffectsInsideOfDeletedTree_complete( @@ -19247,7 +19969,7 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( } if (sibling !== null) { - ensureCorrectReturnPointer(sibling, returnFiber); + sibling.return = returnFiber; nextEffect = sibling; return; } @@ -19275,23 +19997,6 @@ function commitPassiveUnmountInsideDeletedTreeOnFiber( break; } } -} - -var didWarnWrongReturnPointer = false; - -function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { - { - if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) { - didWarnWrongReturnPointer = true; - - error( - "Internal React error: Return pointer is inconsistent " + "with parent." - ); - } - } // TODO: Remove this assignment once we're confident that it won't break - // anything, by checking the warning logs for the above invariant - - fiber.return = expectedReturnFiber; } // TODO: Reuse reappearLayoutEffects traversal here? var COMPONENT_TYPE = 0; @@ -19417,6 +20122,7 @@ var workInProgressRootRenderTargetTime = Infinity; // How long a render is suppo // suspense heuristics and opt out of rendering more content. var RENDER_TIMEOUT_MS = 500; +var workInProgressTransitions = null; function resetRenderTimer() { workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS; @@ -19432,17 +20138,22 @@ var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; var pendingPassiveEffectsLanes = NoLanes; var pendingPassiveProfilerEffects = []; +var pendingPassiveTransitions = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; var nestedUpdateCount = 0; var rootWithNestedUpdates = null; +var isFlushingPassiveEffects = false; +var didScheduleUpdateDuringPassiveEffects = false; var NESTED_PASSIVE_UPDATE_LIMIT = 50; -var nestedPassiveUpdateCount = 0; // If two updates are scheduled within the same event, we should treat their +var nestedPassiveUpdateCount = 0; +var rootWithPassiveNestedUpdates = null; // If two updates are scheduled within the same event, we should treat their // event times as simultaneous, even if the actual clock time has advanced // between the first and second call. var currentEventTime = NoTimestamp; var currentEventTransitionLane = NoLanes; +var isRunningInsertionEffect = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -19545,10 +20256,23 @@ function requestRetryLane(fiber) { function scheduleUpdateOnFiber(fiber, lane, eventTime) { checkForNestedUpdates(); + + { + if (isRunningInsertionEffect) { + error("useInsertionEffect must not schedule updates."); + } + } + var root = markUpdateLaneFromFiberToRoot(fiber, lane); if (root === null) { return null; + } + + { + if (isFlushingPassiveEffects) { + didScheduleUpdateDuringPassiveEffects = true; + } } // Mark that the root has a pending update. markRootUpdated(root, lane, eventTime); @@ -19675,7 +20399,12 @@ function isInterleavedUpdate(fiber, lane) { // TODO: Optimize slightly by comparing to root that fiber belongs to. // Requires some refactoring. Not a big deal though since it's rare for // concurrent apps to have more than a single root. - workInProgressRoot !== null && + (workInProgressRoot !== null || // If the interleaved updates queue hasn't been cleared yet, then + // we should treat this as an interleaved update, too. This is also a + // defensive coding measure in case a new update comes in between when + // rendering has finished and when the interleaved updates are transferred + // to the main queue. + hasInterleavedUpdates()) && (fiber.mode & ConcurrentMode) !== NoMode && // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps), // then don't treat this as an interleaved update. This pattern is // accompanied by a warning but we haven't fully deprecated it yet. We can @@ -20009,7 +20738,11 @@ function finishConcurrentRender(root, exitStatus, lanes) { case RootErrored: { // We should have already attempted to retry this tree. If we reached // this point, it errored again. Commit it. - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; } @@ -20049,14 +20782,23 @@ function finishConcurrentRender(root, exitStatus, lanes) { // immediately, wait for more data to arrive. root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), msUntilTimeout ); break; } } // The work expired. Commit immediately. - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; } @@ -20087,20 +20829,33 @@ function finishConcurrentRender(root, exitStatus, lanes) { // Instead of committing the fallback immediately, wait for more data // to arrive. root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), _msUntilTimeout ); break; } } // Commit the placeholder. - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; } case RootCompleted: { // The work completed. Ready to commit. - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; } @@ -20235,7 +20990,11 @@ function performSyncWorkOnRoot(root) { var finishedWork = root.current.alternate; root.finishedWork = finishedWork; root.finishedLanes = lanes; - commitRoot(root, workInProgressRootRecoverableErrors); // Before exiting, make sure there's a callback scheduled for the next + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); // Before exiting, make sure there's a callback scheduled for the next // pending level. ensureRootIsScheduled(root, now()); @@ -20542,6 +21301,8 @@ function renderRootSync(root, lanes) { movePendingFibersToMemoized(root, lanes); } } + + workInProgressTransitions = getTransitionsForLanes(); prepareFreshStack(root, lanes); } @@ -20602,6 +21363,8 @@ function renderRootConcurrent(root, lanes) { movePendingFibersToMemoized(root, lanes); } } + + workInProgressTransitions = getTransitionsForLanes(); resetRenderTimer(); prepareFreshStack(root, lanes); } @@ -20760,7 +21523,7 @@ function completeUnitOfWork(unitOfWork) { } } -function commitRoot(root, recoverableErrors) { +function commitRoot(root, recoverableErrors, transitions) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); @@ -20769,7 +21532,12 @@ function commitRoot(root, recoverableErrors) { try { ReactCurrentBatchConfig$2.transition = null; setCurrentUpdatePriority(DiscreteEventPriority); - commitRootImpl(root, recoverableErrors, previousUpdateLanePriority); + commitRootImpl( + root, + recoverableErrors, + transitions, + previousUpdateLanePriority + ); } finally { ReactCurrentBatchConfig$2.transition = prevTransition; setCurrentUpdatePriority(previousUpdateLanePriority); @@ -20778,7 +21546,12 @@ function commitRoot(root, recoverableErrors) { return null; } -function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { +function commitRootImpl( + root, + recoverableErrors, + transitions, + renderPriorityLevel +) { do { // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which // means `flushPassiveEffects` will sometimes result in additional @@ -20846,6 +21619,13 @@ function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { ) { if (!rootDoesHavePassiveEffects) { rootDoesHavePassiveEffects = true; + // to store it in pendingPassiveTransitions until they get processed + // We need to pass this through as an argument to commitRoot + // because workInProgressTransitions might have changed between + // the previous render and commit if we throttle the commit + // with setTimeout + + pendingPassiveTransitions = transitions; scheduleCallback$1(NormalPriority, function() { flushPassiveEffects(); // This render triggered passive effects: release the root cache pool // *after* passive effects fire to avoid freeing a cache pool that may @@ -20929,6 +21709,11 @@ function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { rootDoesHavePassiveEffects = false; rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; + } else { + { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root @@ -21056,9 +21841,12 @@ function enqueuePendingPassiveProfilerEffect(fiber) { function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { return false; - } + } // Cache and clear the transitions flag + var transitions = pendingPassiveTransitions; + pendingPassiveTransitions = null; var root = rootWithPendingPassiveEffects; + var lanes = pendingPassiveEffectsLanes; rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects. // Figure out why and fix it. It's not causing any known issues (probably // because it's only used for profiling), but it's a refactor hazard. @@ -21069,10 +21857,15 @@ function flushPassiveEffectsImpl() { throw new Error("Cannot flush passive effects while already rendering."); } + { + isFlushingPassiveEffects = true; + didScheduleUpdateDuringPassiveEffects = false; + } + var prevExecutionContext = executionContext; executionContext |= CommitContext; commitPassiveUnmountEffects(root.current); - commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects + commitPassiveMountEffects(root, root.current, lanes, transitions); // TODO: Move to commitPassiveMountEffects { var profilerEffects = pendingPassiveProfilerEffects; @@ -21085,11 +21878,25 @@ function flushPassiveEffectsImpl() { } executionContext = prevExecutionContext; - flushSyncCallbacks(); // If additional passive effects were scheduled, increment a counter. If this - // exceeds the limit, we'll fire a warning. + flushSyncCallbacks(); - nestedPassiveUpdateCount = - rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; // TODO: Move to commitPassiveMountEffects + { + // If additional passive effects were scheduled, increment a counter. If this + // exceeds the limit, we'll fire a warning. + if (didScheduleUpdateDuringPassiveEffects) { + if (root === rootWithPassiveNestedUpdates) { + nestedPassiveUpdateCount++; + } else { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = root; + } + } else { + nestedPassiveUpdateCount = 0; + } + + isFlushingPassiveEffects = false; + didScheduleUpdateDuringPassiveEffects = false; + } // TODO: Move to commitPassiveMountEffects onPostCommitRoot(root); @@ -21139,6 +21946,11 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { + { + reportUncaughtErrorInDEV(error$1); + setIsRunningInsertionEffect(false); + } + if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. @@ -21263,13 +22075,42 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { ensureRootIsScheduled(root, eventTime); } } + +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState; + var retryLane = NoLane; + + if (suspenseState !== null) { + retryLane = suspenseState.retryLane; + } + + retryTimedOutBoundary(boundaryFiber, retryLane); +} function resolveRetryWakeable(boundaryFiber, wakeable) { var retryLane = NoLane; // Default var retryCache; - { - retryCache = boundaryFiber.stateNode; + switch (boundaryFiber.tag) { + case SuspenseComponent: + retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + + if (suspenseState !== null) { + retryLane = suspenseState.retryLane; + } + + break; + + case SuspenseListComponent: + retryCache = boundaryFiber.stateNode; + break; + + default: + throw new Error( + "Pinged unknown suspense boundary type. " + + "This is probably a bug in React." + ); } if (retryCache !== null) { @@ -21320,6 +22161,7 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; error( "Maximum update depth exceeded. This can happen when a component " + @@ -21423,11 +22265,13 @@ var beginWork$1; return beginWork(current, unitOfWork, lanes); } catch (originalError) { if ( - originalError !== null && - typeof originalError === "object" && - typeof originalError.then === "function" + didSuspendOrErrorWhileHydratingDEV() || + (originalError !== null && + typeof originalError === "object" && + typeof originalError.then === "function") ) { - // Don't replay promises. Treat everything else like an error. + // Don't replay promises. + // Don't replay errors if we are hydrating and have already suspended or handled an error throw originalError; } // Keep this code in sync with handleError; any changes here must have // corresponding changes there. @@ -21653,6 +22497,12 @@ function warnIfSuspenseResolutionNotWrappedWithActDEV(root) { } } +function setIsRunningInsertionEffect(isRunning) { + { + isRunningInsertionEffect = isRunning; + } +} + /* eslint-disable react-internal/prod-error-codes */ var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. @@ -22787,7 +23637,8 @@ function createFiberRoot( isDehydrated: hydrate, cache: null, // not enabled yet - transitions: null + transitions: null, + pendingSuspenseBoundaries: null }; uninitializedFiber.memoizedState = _initialState; } @@ -22796,7 +23647,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.0.0-experimental-34aa5cfe0-20220329"; +var ReactVersion = "18.2.0-next-d300cebde-20220601"; function createPortal( children, diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js index 99e8fc66bc9..5e26abc86f4 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactNativeRenderer-prod * @preventMunge - * @generated SignedSource<<08a279093988c36b477bd72fa59e144d>> + * @generated SignedSource<<9f59a543175acb00b00023e9ed7d8c38>> */ "use strict"; @@ -1017,7 +1017,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_220 = { +var injectedNamesToPlugins$jscomp$inline_225 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1063,33 +1063,33 @@ var injectedNamesToPlugins$jscomp$inline_220 = { } } }, - isOrderingDirty$jscomp$inline_221 = !1, - pluginName$jscomp$inline_222; -for (pluginName$jscomp$inline_222 in injectedNamesToPlugins$jscomp$inline_220) + isOrderingDirty$jscomp$inline_226 = !1, + pluginName$jscomp$inline_227; +for (pluginName$jscomp$inline_227 in injectedNamesToPlugins$jscomp$inline_225) if ( - injectedNamesToPlugins$jscomp$inline_220.hasOwnProperty( - pluginName$jscomp$inline_222 + injectedNamesToPlugins$jscomp$inline_225.hasOwnProperty( + pluginName$jscomp$inline_227 ) ) { - var pluginModule$jscomp$inline_223 = - injectedNamesToPlugins$jscomp$inline_220[pluginName$jscomp$inline_222]; + var pluginModule$jscomp$inline_228 = + injectedNamesToPlugins$jscomp$inline_225[pluginName$jscomp$inline_227]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_222) || - namesToPlugins[pluginName$jscomp$inline_222] !== - pluginModule$jscomp$inline_223 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_227) || + namesToPlugins[pluginName$jscomp$inline_227] !== + pluginModule$jscomp$inline_228 ) { - if (namesToPlugins[pluginName$jscomp$inline_222]) + if (namesToPlugins[pluginName$jscomp$inline_227]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_222 + "`.") + (pluginName$jscomp$inline_227 + "`.") ); namesToPlugins[ - pluginName$jscomp$inline_222 - ] = pluginModule$jscomp$inline_223; - isOrderingDirty$jscomp$inline_221 = !0; + pluginName$jscomp$inline_227 + ] = pluginModule$jscomp$inline_228; + isOrderingDirty$jscomp$inline_226 = !0; } } -isOrderingDirty$jscomp$inline_221 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_226 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1923,6 +1923,12 @@ function getLanesToRetrySynchronouslyOnError(root) { root = root.pendingLanes & -1073741825; return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; } +function claimNextTransitionLane() { + var lane = nextTransitionLane; + nextTransitionLane <<= 1; + 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64); + return lane; +} function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; @@ -2152,7 +2158,28 @@ function flushSyncCallbacks() { } return null; } -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +var forkStack = [], + forkStackIndex = 0, + treeForkProvider = null, + idStack = [], + idStackIndex = 0, + treeContextProvider = null; +function popTreeContext(workInProgress) { + for (; workInProgress === treeForkProvider; ) + (treeForkProvider = forkStack[--forkStackIndex]), + (forkStack[forkStackIndex] = null), + --forkStackIndex, + (forkStack[forkStackIndex] = null); + for (; workInProgress === treeContextProvider; ) + (treeContextProvider = idStack[--idStackIndex]), + (idStack[idStackIndex] = null), + --idStackIndex, + (idStack[idStackIndex] = null), + --idStackIndex, + (idStack[idStackIndex] = null); +} +var hydrationErrors = null, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function shallowEqual(objA, objB) { if (objectIs(objA, objB)) return !0; if ( @@ -2309,9 +2336,7 @@ function enqueueUpdate(fiber, update) { var updateQueue = fiber.updateQueue; null !== updateQueue && ((updateQueue = updateQueue.shared), - null !== workInProgressRoot && - 0 !== (fiber.mode & 1) && - 0 === (executionContext & 2) + isInterleavedUpdate(fiber) ? ((fiber = updateQueue.interleaved), null === fiber ? ((update.next = update), @@ -2679,26 +2704,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var forkStack = [], - forkStackIndex = 0, - treeForkProvider = null, - idStack = [], - idStackIndex = 0, - treeContextProvider = null; -function popTreeContext(workInProgress) { - for (; workInProgress === treeForkProvider; ) - (treeForkProvider = forkStack[--forkStackIndex]), - (forkStack[forkStackIndex] = null), - --forkStackIndex, - (forkStack[forkStackIndex] = null); - for (; workInProgress === treeContextProvider; ) - (treeContextProvider = idStack[--idStackIndex]), - (idStack[idStackIndex] = null), - --idStackIndex, - (idStack[idStackIndex] = null), - --idStackIndex, - (idStack[idStackIndex] = null); -} function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2761,6 +2766,10 @@ function throwOnInvalidObjectType(returnFiber, newChild) { "). If you meant to render a collection of children, use an array instead." ); } +function resolveLazy(lazyType) { + var init = lazyType._init; + return init(lazyType._payload); +} function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { @@ -2833,7 +2842,14 @@ function ChildReconciler(shouldTrackSideEffects) { lanes, element.key ); - if (null !== current && current.elementType === elementType) + if ( + null !== current && + (current.elementType === elementType || + ("object" === typeof elementType && + null !== elementType && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === current.type)) + ) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2924,6 +2940,9 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild.return = returnFiber), newChild ); + case REACT_LAZY_TYPE: + var init = newChild._init; + return createChild(returnFiber, init(newChild._payload), lanes); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -2959,6 +2978,11 @@ function ChildReconciler(shouldTrackSideEffects) { return newChild.key === key ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; + case REACT_LAZY_TYPE: + return ( + (key = newChild._init), + updateSlot(returnFiber, oldFiber, key(newChild._payload), lanes) + ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key @@ -3001,6 +3025,15 @@ function ChildReconciler(shouldTrackSideEffects) { ) || null), updatePortal(returnFiber, existingChildren, newChild, lanes) ); + case REACT_LAZY_TYPE: + var init = newChild._init; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + init(newChild._payload), + lanes + ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -3178,7 +3211,12 @@ function ChildReconciler(shouldTrackSideEffects) { }); return iteratorFn; } - return function(returnFiber, currentFirstChild, newChild, lanes) { + function reconcileChildFibers( + returnFiber, + currentFirstChild, + newChild, + lanes + ) { "object" === typeof newChild && null !== newChild && newChild.type === REACT_FRAGMENT_TYPE && @@ -3206,7 +3244,13 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; break a; } - } else if (child.elementType === key) { + } else if ( + child.elementType === key || + ("object" === typeof key && + null !== key && + key.$$typeof === REACT_LAZY_TYPE && + resolveLazy(key) === child.type) + ) { deleteRemainingChildren(returnFiber, child.sibling); currentFirstChild = useFiber(child, newChild.props); currentFirstChild.ref = coerceRef( @@ -3287,6 +3331,16 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; } return placeSingleChild(returnFiber); + case REACT_LAZY_TYPE: + return ( + (child = newChild._init), + reconcileChildFibers( + returnFiber, + currentFirstChild, + child(newChild._payload), + lanes + ) + ); } if (isArrayImpl(newChild)) return reconcileChildrenArray( @@ -3322,7 +3376,8 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber)) : deleteRemainingChildren(returnFiber, currentFirstChild); - }; + } + return reconcileChildFibers; } var reconcileChildFibers = ChildReconciler(!0), mountChildFibers = ChildReconciler(!1), @@ -3809,6 +3864,19 @@ function updateMemo(nextCreate, deps) { hook.memoizedState = [nextCreate, deps]; return nextCreate; } +function updateDeferredValueImpl(hook, prevValue, value) { + if (0 === (renderLanes & 21)) + return ( + hook.baseState && ((hook.baseState = !1), (didReceiveUpdate = !0)), + (hook.memoizedState = value) + ); + objectIs(value, prevValue) || + ((value = claimNextTransitionLane()), + (currentlyRenderingFiber$1.lanes |= value), + (workInProgressRootSkippedLanes |= value), + (hook.baseState = !0)); + return prevValue; +} function startTransition(setPending, callback) { var previousPriority = currentUpdatePriority; currentUpdatePriority = @@ -3890,9 +3958,7 @@ function enqueueRenderPhaseUpdate(queue, update) { queue.pending = update; } function enqueueUpdate$1(fiber, queue, update) { - null !== workInProgressRoot && - 0 !== (fiber.mode & 1) && - 0 === (executionContext & 2) + isInterleavedUpdate(fiber) ? ((fiber = queue.interleaved), null === fiber ? ((update.next = update), @@ -3997,29 +4063,14 @@ var ContextOnlyDispatcher = { useState: mountState, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _mountState = mountState(value), - prevValue = _mountState[0], - setValue = _mountState[1]; - mountEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + return (mountWorkInProgressHook().memoizedState = value); }, useTransition: function() { - var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = startTransition.bind(null, _mountState2[1]); - mountWorkInProgressHook().memoizedState = _mountState2; - return [isPending, _mountState2]; + var _mountState = mountState(!1), + isPending = _mountState[0]; + _mountState = startTransition.bind(null, _mountState[1]); + mountWorkInProgressHook().memoizedState = _mountState; + return [isPending, _mountState]; }, useMutableSource: function() {}, useSyncExternalStore: function(subscribe, getSnapshot) { @@ -4073,22 +4124,8 @@ var ContextOnlyDispatcher = { }, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _updateState = updateReducer(basicStateReducer), - prevValue = _updateState[0], - setValue = _updateState[1]; - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + return updateDeferredValueImpl(hook, currentHook.memoizedState, value); }, useTransition: function() { var isPending = updateReducer(basicStateReducer)[0], @@ -4116,22 +4153,10 @@ var ContextOnlyDispatcher = { }, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + return null === currentHook + ? (hook.memoizedState = value) + : updateDeferredValueImpl(hook, currentHook.memoizedState, value); }, useTransition: function() { var isPending = rerenderReducer(basicStateReducer)[0], @@ -4228,388 +4253,6 @@ function attachPingListener(root, wakeable, lanes) { (root = pingSuspendedRoot.bind(null, root, wakeable, lanes)), wakeable.then(root, root)); } -var appendAllChildren, updateHostContainer, updateHostComponent, updateHostText; -appendAllChildren = function(parent, workInProgress) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); - else if (4 !== node.tag && null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -}; -updateHostContainer = function() {}; -updateHostComponent = function(current, workInProgress, type, newProps) { - current.memoizedProps !== newProps && - (requiredContext(contextStackCursor$1.current), - (workInProgress.updateQueue = UPDATE_SIGNAL)) && - (workInProgress.flags |= 4); -}; -updateHostText = function(current, workInProgress, oldText, newText) { - oldText !== newText && (workInProgress.flags |= 4); -}; -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var lastTailNode$35 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$35 = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === lastTailNode$35 - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (lastTailNode$35.sibling = null); - } -} -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - for (var child$36 = completedWork.child; null !== child$36; ) - (newChildLanes |= child$36.lanes | child$36.childLanes), - (subtreeFlags |= child$36.subtreeFlags & 14680064), - (subtreeFlags |= child$36.flags & 14680064), - (child$36.return = completedWork), - (child$36 = child$36.sibling); - else - for (child$36 = completedWork.child; null !== child$36; ) - (newChildLanes |= child$36.lanes | child$36.childLanes), - (subtreeFlags |= child$36.subtreeFlags), - (subtreeFlags |= child$36.flags), - (child$36.return = completedWork), - (child$36 = child$36.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; - popTreeContext(workInProgress); - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); - case 3: - return ( - (newProps = workInProgress.stateNode), - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - resetWorkInProgressVersions(), - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)), - (null !== current && null !== current.child) || - null === current || - (current.memoizedState.isDehydrated && - 0 === (workInProgress.flags & 256)) || - (workInProgress.flags |= 1024), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 5: - popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent( - current, - workInProgress, - type, - newProps, - renderLanes - ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 512); - else { - if (!newProps) { - if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - bubbleProperties(workInProgress); - return null; - } - requiredContext(contextStackCursor$1.current); - current = allocateTag(); - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - ReactNativePrivateInterface.UIManager.createView( - current, - type.uiViewClassName, - renderLanes, - updatePayload - ); - renderLanes = new ReactNativeFiberHostComponent( - current, - type, - workInProgress - ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - appendAllChildren(renderLanes, workInProgress, !1, !1); - workInProgress.stateNode = renderLanes; - finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 512); - } - bubbleProperties(workInProgress); - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - if (!requiredContext(contextStackCursor$1.current).isInAParentText) - throw Error( - "Text strings must be rendered within a component." - ); - renderLanes = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - renderLanes, - "RCTRawText", - current, - { text: newProps } - ); - instanceCache.set(renderLanes, workInProgress); - workInProgress.stateNode = renderLanes; - } - bubbleProperties(workInProgress); - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) - return (workInProgress.lanes = renderLanes), workInProgress; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - null === newProps || - renderLanes || - ((workInProgress.child.flags |= 8192), - 0 !== (workInProgress.mode & 1) && - (null === current || 0 !== (suspenseStackCursor.current & 1) - ? 0 === workInProgressRootExitStatus && - (workInProgressRootExitStatus = 3) - : renderDidSuspendDelayIfPossible())); - null !== workInProgress.updateQueue && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); - return null; - case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); - case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); - case 19: - pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; - if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); - else { - if ( - 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (type = current), - (renderLanes.flags &= 14680066), - (updatePayload = renderLanes.alternate), - null === updatePayload - ? ((renderLanes.childLanes = 0), - (renderLanes.lanes = type), - (renderLanes.child = null), - (renderLanes.subtreeFlags = 0), - (renderLanes.memoizedProps = null), - (renderLanes.memoizedState = null), - (renderLanes.updateQueue = null), - (renderLanes.dependencies = null), - (renderLanes.stateNode = null)) - : ((renderLanes.childLanes = updatePayload.childLanes), - (renderLanes.lanes = updatePayload.lanes), - (renderLanes.child = updatePayload.child), - (renderLanes.subtreeFlags = 0), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = - updatePayload.memoizedProps), - (renderLanes.memoizedState = - updatePayload.memoizedState), - (renderLanes.updateQueue = updatePayload.updateQueue), - (renderLanes.type = updatePayload.type), - (type = updatePayload.dependencies), - (renderLanes.dependencies = - null === type - ? null - : { - lanes: type.lanes, - firstContext: type.firstContext - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== type.tail && - now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && - !updatePayload.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now() - type.renderingStartTime > - workInProgressRootRenderTargetTime && - 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - type.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (type.last = updatePayload)); - } - if (null !== type.tail) - return ( - (workInProgress = type.tail), - (type.rendering = workInProgress), - (type.tail = workInProgress.sibling), - (type.renderingStartTime = now()), - (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), - workInProgress - ); - bubbleProperties(workInProgress); - return null; - case 22: - case 23: - return ( - popRenderLanes(), - (newProps = null !== workInProgress.memoizedState), - null !== current && - (null !== current.memoizedState) !== newProps && - (workInProgress.flags |= 8192), - newProps && 0 !== (workInProgress.mode & 1) - ? 0 !== (subtreeRenderLanes & 1073741824) && - (bubbleProperties(workInProgress), - workInProgress.subtreeFlags & 6 && (workInProgress.flags |= 8192)) - : bubbleProperties(workInProgress), - null - ); - case 24: - return null; - case 25: - return null; - } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); -} var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { @@ -4712,18 +4355,24 @@ function updateSimpleMemoComponent( nextProps, renderLanes ) { - if ( - null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes))) - 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); - else - return ( - (workInProgress.lanes = current.lanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); + if (null !== current) { + var prevProps = current.memoizedProps; + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref + ) + if ( + ((didReceiveUpdate = !1), + (workInProgress.pendingProps = nextProps = prevProps), + 0 !== (current.lanes & renderLanes)) + ) + 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); + else + return ( + (workInProgress.lanes = current.lanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + } return updateFunctionComponent( current, workInProgress, @@ -4738,7 +4387,11 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { prevState = null !== current ? current.memoizedState : null; if ("hidden" === nextProps.mode) if (0 === (workInProgress.mode & 1)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + (workInProgress.memoizedState = { + baseLanes: 0, + cachePool: null, + transitions: null + }), push(subtreeRenderLanesCursor, subtreeRenderLanes), (subtreeRenderLanes |= renderLanes); else { @@ -4751,14 +4404,19 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { (workInProgress.lanes = workInProgress.childLanes = 1073741824), (workInProgress.memoizedState = { baseLanes: current, - cachePool: null + cachePool: null, + transitions: null }), (workInProgress.updateQueue = null), push(subtreeRenderLanesCursor, subtreeRenderLanes), (subtreeRenderLanes |= current), null ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + workInProgress.memoizedState = { + baseLanes: 0, + cachePool: null, + transitions: null + }; nextProps = null !== prevState ? prevState.baseLanes : renderLanes; push(subtreeRenderLanesCursor, subtreeRenderLanes); subtreeRenderLanes |= nextProps; @@ -4773,7 +4431,7 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef$1(current, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( (null === current && null !== ref) || @@ -4825,10 +4483,7 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderLanes); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)), + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), constructClassInstance(workInProgress, Component, nextProps), mountClassInstance(workInProgress, Component, nextProps, renderLanes), (nextProps = !0); @@ -5022,7 +4677,7 @@ function finishClassComponent( hasContext, renderLanes ) { - markRef$1(current, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( @@ -5068,14 +4723,15 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, treeContext: null, retryLane: 0 }; function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: null }; + return { baseLanes: renderLanes, cachePool: null, transitions: null }; } function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, + didSuspend = 0 !== (workInProgress.flags & 128), JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || + (JSCompiler_temp = didSuspend) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 @@ -5085,167 +4741,297 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext |= 1; push(suspenseStackCursor, suspenseContext & 1); if (null === current) { - suspenseContext = nextProps.children; - current = nextProps.fallback; - if (showFallback) + current = workInProgress.memoizedState; + if (null !== current && null !== current.dehydrated) return ( - (showFallback = workInProgress.mode), - (nextProps = workInProgress.child), - (suspenseContext = { mode: "hidden", children: suspenseContext }), - 0 === (showFallback & 1) && null !== nextProps - ? ((nextProps.childLanes = 0), - (nextProps.pendingProps = suspenseContext)) - : (nextProps = createFiberFromOffscreen( - suspenseContext, - showFallback, + 0 === (workInProgress.mode & 1) + ? (workInProgress.lanes = 1) + : shim() + ? (workInProgress.lanes = 8) + : (workInProgress.lanes = 1073741824), + null + ); + didSuspend = nextProps.children; + current = nextProps.fallback; + return showFallback + ? ((nextProps = workInProgress.mode), + (showFallback = workInProgress.child), + (didSuspend = { mode: "hidden", children: didSuspend }), + 0 === (nextProps & 1) && null !== showFallback + ? ((showFallback.childLanes = 0), + (showFallback.pendingProps = didSuspend)) + : (showFallback = createFiberFromOffscreen( + didSuspend, + nextProps, 0, null )), (current = createFiberFromFragment( current, - showFallback, + nextProps, renderLanes, null )), - (nextProps.return = workInProgress), + (showFallback.return = workInProgress), (current.return = workInProgress), - (nextProps.sibling = current), - (workInProgress.child = nextProps), + (showFallback.sibling = current), + (workInProgress.child = showFallback), (workInProgress.child.memoizedState = mountSuspenseOffscreenState( renderLanes )), (workInProgress.memoizedState = SUSPENDED_MARKER), - current - ); - renderLanes = createFiberFromOffscreen( - { mode: "visible", children: suspenseContext }, - workInProgress.mode, - 0, - null - ); - renderLanes.return = workInProgress; - return (workInProgress.child = renderLanes); + current) + : mountSuspensePrimaryChildren(workInProgress, didSuspend); } - if (null !== current.memoizedState) { - if (showFallback) - return ( - (showFallback = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (nextProps = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (nextProps.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (nextProps.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - showFallback - ); - renderLanes = updateSuspensePrimaryChildren( + suspenseContext = current.memoizedState; + if ( + null !== suspenseContext && + ((JSCompiler_temp = suspenseContext.dehydrated), null !== JSCompiler_temp) + ) + return updateDehydratedSuspenseComponent( current, workInProgress, - nextProps.children, + didSuspend, + nextProps, + JSCompiler_temp, + suspenseContext, renderLanes ); - workInProgress.memoizedState = null; - return renderLanes; + if (showFallback) { + showFallback = nextProps.fallback; + didSuspend = workInProgress.mode; + suspenseContext = current.child; + JSCompiler_temp = suspenseContext.sibling; + var primaryChildProps = { mode: "hidden", children: nextProps.children }; + 0 === (didSuspend & 1) && workInProgress.child !== suspenseContext + ? ((nextProps = workInProgress.child), + (nextProps.childLanes = 0), + (nextProps.pendingProps = primaryChildProps), + (workInProgress.deletions = null)) + : ((nextProps = createWorkInProgress(suspenseContext, primaryChildProps)), + (nextProps.subtreeFlags = suspenseContext.subtreeFlags & 14680064)); + null !== JSCompiler_temp + ? (showFallback = createWorkInProgress(JSCompiler_temp, showFallback)) + : ((showFallback = createFiberFromFragment( + showFallback, + didSuspend, + renderLanes, + null + )), + (showFallback.flags |= 2)); + showFallback.return = workInProgress; + nextProps.return = workInProgress; + nextProps.sibling = showFallback; + workInProgress.child = nextProps; + nextProps = showFallback; + showFallback = workInProgress.child; + didSuspend = current.child.memoizedState; + didSuspend = + null === didSuspend + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: didSuspend.baseLanes | renderLanes, + cachePool: null, + transitions: didSuspend.transitions + }; + showFallback.memoizedState = didSuspend; + showFallback.childLanes = current.childLanes & ~renderLanes; + workInProgress.memoizedState = SUSPENDED_MARKER; + return nextProps; } - if (showFallback) - return ( - (showFallback = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (nextProps = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (nextProps.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (nextProps.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - showFallback - ); - renderLanes = updateSuspensePrimaryChildren( - current, - workInProgress, - nextProps.children, - renderLanes - ); - workInProgress.memoizedState = null; - return renderLanes; -} -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - primaryChildren = createWorkInProgress(currentPrimaryChildFragment, { + showFallback = current.child; + current = showFallback.sibling; + nextProps = createWorkInProgress(showFallback, { mode: "visible", - children: primaryChildren + children: nextProps.children }); - 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); - primaryChildren.return = workInProgress; - primaryChildren.sibling = null; + 0 === (workInProgress.mode & 1) && (nextProps.lanes = renderLanes); + nextProps.return = workInProgress; + nextProps.sibling = null; null !== current && ((renderLanes = workInProgress.deletions), null === renderLanes ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) : renderLanes.push(current)); + workInProgress.child = nextProps; + workInProgress.memoizedState = null; + return nextProps; +} +function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { + primaryChildren = createFiberFromOffscreen( + { mode: "visible", children: primaryChildren }, + workInProgress.mode, + 0, + null + ); + primaryChildren.return = workInProgress; return (workInProgress.child = primaryChildren); } -function updateSuspenseFallbackChildren( +function retrySuspenseComponentWithoutHydrating( current, workInProgress, - primaryChildren, - fallbackChildren, + renderLanes, + recoverableError +) { + null !== recoverableError && + (null === hydrationErrors + ? (hydrationErrors = [recoverableError]) + : hydrationErrors.push(recoverableError)); + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + current = mountSuspensePrimaryChildren( + workInProgress, + workInProgress.pendingProps.children + ); + current.flags |= 2; + workInProgress.memoizedState = null; + return current; +} +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + nextProps, + suspenseInstance, + suspenseState, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, - primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current - ? ((primaryChildren = workInProgress.child), - (primaryChildren.childLanes = 0), - (primaryChildren.pendingProps = primaryChildProps), - (workInProgress.deletions = null)) - : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 14680064)); - null !== currentFallbackChildFragment - ? (fallbackChildren = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - )) - : ((fallbackChildren = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, + if (didSuspend) { + if (workInProgress.flags & 256) + return ( + (workInProgress.flags &= -257), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + Error( + "There was an error while hydrating this Suspense boundary. Switched to client rendering." + ) + ) + ); + if (null !== workInProgress.memoizedState) + return ( + (workInProgress.child = current.child), + (workInProgress.flags |= 128), null - )), - (fallbackChildren.flags |= 2)); - fallbackChildren.return = workInProgress; - primaryChildren.return = workInProgress; - primaryChildren.sibling = fallbackChildren; - workInProgress.child = primaryChildren; - return fallbackChildren; + ); + suspenseState = nextProps.fallback; + didSuspend = workInProgress.mode; + nextProps = createFiberFromOffscreen( + { mode: "visible", children: nextProps.children }, + didSuspend, + 0, + null + ); + suspenseState = createFiberFromFragment( + suspenseState, + didSuspend, + renderLanes, + null + ); + suspenseState.flags |= 2; + nextProps.return = workInProgress; + suspenseState.return = workInProgress; + nextProps.sibling = suspenseState; + workInProgress.child = nextProps; + 0 !== (workInProgress.mode & 1) && + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return suspenseState; + } + if (0 === (workInProgress.mode & 1)) + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + if (shim()) + return ( + (suspenseState = shim().errorMessage), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + suspenseState + ? Error(suspenseState) + : Error( + "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." + ) + ) + ); + didSuspend = 0 !== (renderLanes & current.childLanes); + if (didReceiveUpdate || didSuspend) { + nextProps = workInProgressRoot; + if (null !== nextProps) { + switch (renderLanes & -renderLanes) { + case 4: + didSuspend = 2; + break; + case 16: + didSuspend = 8; + break; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + didSuspend = 32; + break; + case 536870912: + didSuspend = 268435456; + break; + default: + didSuspend = 0; + } + nextProps = + 0 !== (didSuspend & (nextProps.suspendedLanes | renderLanes)) + ? 0 + : didSuspend; + 0 !== nextProps && + nextProps !== suspenseState.retryLane && + ((suspenseState.retryLane = nextProps), + scheduleUpdateOnFiber(current, nextProps, -1)); + } + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + Error( + "This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition." + ) + ); + } + if (shim()) + return ( + (workInProgress.flags |= 128), + (workInProgress.child = current.child), + retryDehydratedSuspenseBoundary.bind(null, current), + shim(), + null + ); + current = mountSuspensePrimaryChildren(workInProgress, nextProps.children); + current.flags |= 4096; + return current; } function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes |= renderLanes; @@ -5364,6 +5150,13 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { } return workInProgress.child; } +function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + 0 === (workInProgress.mode & 1) && + null !== current && + ((current.alternate = null), + (workInProgress.alternate = null), + (workInProgress.flags |= 2)); +} function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); workInProgressRootSkippedLanes |= workInProgress.lanes; @@ -5411,7 +5204,14 @@ function attemptEarlyBailoutIfNoScheduledUpdate( context._currentValue = nextValue; break; case 13: - if (null !== workInProgress.memoizedState) { + context = workInProgress.memoizedState; + if (null !== context) { + if (null !== context.dehydrated) + return ( + push(suspenseStackCursor, suspenseStackCursor.current & 1), + (workInProgress.flags |= 128), + null + ); if (0 !== (renderLanes & workInProgress.child.childLanes)) return updateSuspenseComponent(current, workInProgress, renderLanes); push(suspenseStackCursor, suspenseStackCursor.current & 1); @@ -5452,6 +5252,416 @@ function attemptEarlyBailoutIfNoScheduledUpdate( } return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } +var appendAllChildren, + updateHostContainer, + updateHostComponent$1, + updateHostText$1; +appendAllChildren = function(parent, workInProgress) { + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); + else if (4 !== node.tag && null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +}; +updateHostContainer = function() {}; +updateHostComponent$1 = function(current, workInProgress, type, newProps) { + current.memoizedProps !== newProps && + (requiredContext(contextStackCursor$1.current), + (workInProgress.updateQueue = UPDATE_SIGNAL)) && + (workInProgress.flags |= 4); +}; +updateHostText$1 = function(current, workInProgress, oldText, newText) { + oldText !== newText && (workInProgress.flags |= 4); +}; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var lastTailNode$60 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$60 = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === lastTailNode$60 + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (lastTailNode$60.sibling = null); + } +} +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$61 = completedWork.child; null !== child$61; ) + (newChildLanes |= child$61.lanes | child$61.childLanes), + (subtreeFlags |= child$61.subtreeFlags & 14680064), + (subtreeFlags |= child$61.flags & 14680064), + (child$61.return = completedWork), + (child$61 = child$61.sibling); + else + for (child$61 = completedWork.child; null !== child$61; ) + (newChildLanes |= child$61.lanes | child$61.childLanes), + (subtreeFlags |= child$61.subtreeFlags), + (subtreeFlags |= child$61.flags), + (child$61.return = completedWork), + (child$61 = child$61.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + popTreeContext(workInProgress); + switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return bubbleProperties(workInProgress), null; + case 1: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 3: + return ( + (renderLanes = workInProgress.stateNode), + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + resetWorkInProgressVersions(), + renderLanes.pendingContext && + ((renderLanes.context = renderLanes.pendingContext), + (renderLanes.pendingContext = null)), + (null !== current && null !== current.child) || + null === current || + (current.memoizedState.isDehydrated && + 0 === (workInProgress.flags & 256)) || + ((workInProgress.flags |= 1024), + null !== hydrationErrors && + (queueRecoverableErrors(hydrationErrors), + (hydrationErrors = null))), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 5: + popHostContext(workInProgress); + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + renderLanes + ), + current.ref !== workInProgress.ref && (workInProgress.flags |= 512); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + bubbleProperties(workInProgress); + return null; + } + requiredContext(contextStackCursor$1.current); + current = allocateTag(); + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + type.validAttributes + ); + ReactNativePrivateInterface.UIManager.createView( + current, + type.uiViewClassName, + renderLanes, + updatePayload + ); + renderLanes = new ReactNativeFiberHostComponent( + current, + type, + workInProgress + ); + instanceCache.set(current, workInProgress); + instanceProps.set(current, newProps); + appendAllChildren(renderLanes, workInProgress, !1, !1); + workInProgress.stateNode = renderLanes; + finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 512); + } + bubbleProperties(workInProgress); + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText$1( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + if (!requiredContext(contextStackCursor$1.current).isInAParentText) + throw Error( + "Text strings must be rendered within a component." + ); + renderLanes = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + renderLanes, + "RCTRawText", + current, + { text: newProps } + ); + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; + } + bubbleProperties(workInProgress); + return null; + case 13: + pop(suspenseStackCursor); + newProps = workInProgress.memoizedState; + if ( + null === current || + (null !== current.memoizedState && + null !== current.memoizedState.dehydrated) + ) { + if (null !== newProps && null !== newProps.dehydrated) { + if (null === current) { + throw Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ); + throw Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + 0 === (workInProgress.flags & 128) && + (workInProgress.memoizedState = null); + workInProgress.flags |= 4; + bubbleProperties(workInProgress); + type = !1; + } else + null !== hydrationErrors && + (queueRecoverableErrors(hydrationErrors), (hydrationErrors = null)), + (type = !0); + if (!type) return workInProgress.flags & 65536 ? workInProgress : null; + } + if (0 !== (workInProgress.flags & 128)) + return (workInProgress.lanes = renderLanes), workInProgress; + renderLanes = null !== newProps; + renderLanes !== (null !== current && null !== current.memoizedState) && + renderLanes && + ((workInProgress.child.flags |= 8192), + 0 !== (workInProgress.mode & 1) && + (null === current || 0 !== (suspenseStackCursor.current & 1) + ? 0 === workInProgressRootExitStatus && + (workInProgressRootExitStatus = 3) + : renderDidSuspendDelayIfPossible())); + null !== workInProgress.updateQueue && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + return null; + case 4: + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 10: + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor); + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; + if (null === updatePayload) + if (newProps) cutOffTailIfNeeded(type, !1); + else { + if ( + 0 !== workInProgressRootExitStatus || + (null !== current && 0 !== (current.flags & 128)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)); + workInProgress.subtreeFlags = 0; + current = renderLanes; + for (renderLanes = workInProgress.child; null !== renderLanes; ) + (newProps = renderLanes), + (type = current), + (newProps.flags &= 14680066), + (updatePayload = newProps.alternate), + null === updatePayload + ? ((newProps.childLanes = 0), + (newProps.lanes = type), + (newProps.child = null), + (newProps.subtreeFlags = 0), + (newProps.memoizedProps = null), + (newProps.memoizedState = null), + (newProps.updateQueue = null), + (newProps.dependencies = null), + (newProps.stateNode = null)) + : ((newProps.childLanes = updatePayload.childLanes), + (newProps.lanes = updatePayload.lanes), + (newProps.child = updatePayload.child), + (newProps.subtreeFlags = 0), + (newProps.deletions = null), + (newProps.memoizedProps = updatePayload.memoizedProps), + (newProps.memoizedState = updatePayload.memoizedState), + (newProps.updateQueue = updatePayload.updateQueue), + (newProps.type = updatePayload.type), + (type = updatePayload.dependencies), + (newProps.dependencies = + null === type + ? null + : { + lanes: type.lanes, + firstContext: type.firstContext + })), + (renderLanes = renderLanes.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2 + ); + return workInProgress.child; + } + current = current.sibling; + } + null !== type.tail && + now() > workInProgressRootRenderTargetTime && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + } + else { + if (!newProps) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.flags |= 128), + (newProps = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)), + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && + !updatePayload.alternate) + ) + return bubbleProperties(workInProgress), null; + } else + 2 * now() - type.renderingStartTime > + workInProgressRootRenderTargetTime && + 1073741824 !== renderLanes && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = type.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (type.last = updatePayload)); + } + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; + case 22: + case 23: + return ( + popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), + null !== current && + (null !== current.memoizedState) !== renderLanes && + (workInProgress.flags |= 8192), + renderLanes && 0 !== (workInProgress.mode & 1) + ? 0 !== (subtreeRenderLanes & 1073741824) && + (bubbleProperties(workInProgress), + workInProgress.subtreeFlags & 6 && (workInProgress.flags |= 8192)) + : bubbleProperties(workInProgress), + null + ); + case 24: + return null; + case 25: + return null; + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} function unwindWork(current, workInProgress) { popTreeContext(workInProgress); switch (workInProgress.tag) { @@ -5477,13 +5687,20 @@ function unwindWork(current, workInProgress) { case 5: return popHostContext(workInProgress), null; case 13: - return ( - pop(suspenseStackCursor), - (current = workInProgress.flags), - current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), workInProgress) - : null - ); + pop(suspenseStackCursor); + current = workInProgress.memoizedState; + if ( + null !== current && + null !== current.dehydrated && + null === workInProgress.alternate + ) + throw Error( + "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." + ); + current = workInProgress.flags; + return current & 65536 + ? ((workInProgress.flags = (current & -65537) | 128), workInProgress) + : null; case 19: return pop(suspenseStackCursor), null; case 4: @@ -5607,61 +5824,13 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create$77 = effect.create; - effect.destroy = create$77(); + var create$73 = effect.create; + effect.destroy = create$73(); } effect = effect.next; } while (effect !== finishedWork); } } -function commitUnmount(finishedRoot, current, nearestMountedAncestor) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) - try { - injectedHook.onCommitFiberUnmount(rendererID, current); - } catch (err) {} - switch (current.tag) { - case 0: - case 11: - case 14: - case 15: - finishedRoot = current.updateQueue; - if ( - null !== finishedRoot && - ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) - ) { - var effect = (finishedRoot = finishedRoot.next); - do { - var _effect = effect, - destroy = _effect.destroy; - _effect = _effect.tag; - void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(current, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && - safelyCallDestroy(current, nearestMountedAncestor, destroy)); - effect = effect.next; - } while (effect !== finishedRoot); - } - break; - case 1: - safelyDetachRef(current, nearestMountedAncestor); - finishedRoot = current.stateNode; - if ("function" === typeof finishedRoot.componentWillUnmount) - try { - (finishedRoot.props = current.memoizedProps), - (finishedRoot.state = current.memoizedState), - finishedRoot.componentWillUnmount(); - } catch (error) { - captureCommitPhaseError(current, nearestMountedAncestor, error); - } - break; - case 5: - safelyDetachRef(current, nearestMountedAncestor); - break; - case 4: - unmountHostComponents(finishedRoot, current, nearestMountedAncestor); - } -} function detachFiberAfterEffects(fiber) { var alternate = fiber.alternate; null !== alternate && @@ -5700,40 +5869,6 @@ function getHostSibling(fiber) { if (!(fiber.flags & 2)) return fiber.stateNode; } } -function commitPlacement(finishedWork) { - a: { - for (var parent = finishedWork.return; null !== parent; ) { - if (isHostParent(parent)) break a; - parent = parent.return; - } - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } - var parentFiber = parent; - switch (parentFiber.tag) { - case 5: - parent = parentFiber.stateNode; - parentFiber.flags & 32 && (parentFiber.flags &= -33); - parentFiber = getHostSibling(finishedWork); - insertOrAppendPlacementNode(finishedWork, parentFiber, parent); - break; - case 3: - case 4: - parent = parentFiber.stateNode.containerInfo; - parentFiber = getHostSibling(finishedWork); - insertOrAppendPlacementNodeIntoContainer( - finishedWork, - parentFiber, - parent - ); - break; - default: - throw Error( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." - ); - } -} function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { var tag = node.tag; if (5 === tag || 6 === tag) @@ -5814,187 +5949,155 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents( - finishedRoot$jscomp$0, - current, - nearestMountedAncestor$jscomp$0 +var hostParent = null, + hostParentIsContainer = !1; +function recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + parent ) { - for ( - var node = current, - currentParentIsValid = !1, - currentParent, - currentParentIsContainer; - ; - - ) { - if (!currentParentIsValid) { - currentParentIsValid = node.return; - a: for (;;) { - if (null === currentParentIsValid) - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - currentParent = currentParentIsValid.stateNode; - switch (currentParentIsValid.tag) { - case 5: - currentParentIsContainer = !1; - break a; - case 3: - currentParent = currentParent.containerInfo; - currentParentIsContainer = !0; - break a; - case 4: - currentParent = currentParent.containerInfo; - currentParentIsContainer = !0; - break a; - } - currentParentIsValid = currentParentIsValid.return; - } - currentParentIsValid = !0; - } - if (5 === node.tag || 6 === node.tag) { - a: for ( - var finishedRoot = finishedRoot$jscomp$0, - root = node, - nearestMountedAncestor = nearestMountedAncestor$jscomp$0, - node$jscomp$0 = root; - ; - - ) - if ( - (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), - null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) - ) - (node$jscomp$0.child.return = node$jscomp$0), - (node$jscomp$0 = node$jscomp$0.child); - else { - if (node$jscomp$0 === root) break a; - for (; null === node$jscomp$0.sibling; ) { - if (null === node$jscomp$0.return || node$jscomp$0.return === root) - break a; - node$jscomp$0 = node$jscomp$0.return; - } - node$jscomp$0.sibling.return = node$jscomp$0.return; - node$jscomp$0 = node$jscomp$0.sibling; - } - currentParentIsContainer - ? ((finishedRoot = currentParent), - recursivelyUncacheFiberNode(node.stateNode), - ReactNativePrivateInterface.UIManager.manageChildren( - finishedRoot, - [], - [], - [], - [], - [0] - )) - : ((finishedRoot = currentParent), - (nearestMountedAncestor = node.stateNode), - recursivelyUncacheFiberNode(nearestMountedAncestor), - (root = finishedRoot._children), - (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), - root.splice(nearestMountedAncestor, 1), - ReactNativePrivateInterface.UIManager.manageChildren( - finishedRoot._nativeTag, - [], - [], - [], - [], - [nearestMountedAncestor] - )); - } else if (4 === node.tag) { - if (null !== node.child) { - currentParent = node.stateNode.containerInfo; - currentParentIsContainer = !0; - node.child.return = node; - node = node.child; - continue; - } - } else if ( - (commitUnmount( - finishedRoot$jscomp$0, - node, - nearestMountedAncestor$jscomp$0 - ), - null !== node.child) - ) { - node.child.return = node; - node = node.child; - continue; - } - if (node === current) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === current) return; - node = node.return; - 4 === node.tag && (currentParentIsValid = !1); - } - node.sibling.return = node.return; - node = node.sibling; - } + for (parent = parent.child; null !== parent; ) + commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, parent), + (parent = parent.sibling); } -function commitWork(current, finishedWork) { - switch (finishedWork.tag) { +function commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + deletedFiber +) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) + try { + injectedHook.onCommitFiberUnmount(rendererID, deletedFiber); + } catch (err) {} + switch (deletedFiber.tag) { + case 5: + safelyDetachRef(deletedFiber, nearestMountedAncestor); + case 6: + var prevHostParent = hostParent, + prevHostParentIsContainer = hostParentIsContainer; + hostParent = null; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + hostParent = prevHostParent; + hostParentIsContainer = prevHostParentIsContainer; + null !== hostParent && + (hostParentIsContainer + ? ((finishedRoot = hostParent), + recursivelyUncacheFiberNode(deletedFiber.stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + finishedRoot, + [], + [], + [], + [], + [0] + )) + : ((finishedRoot = hostParent), + (nearestMountedAncestor = deletedFiber.stateNode), + recursivelyUncacheFiberNode(nearestMountedAncestor), + (deletedFiber = finishedRoot._children), + (nearestMountedAncestor = deletedFiber.indexOf( + nearestMountedAncestor + )), + deletedFiber.splice(nearestMountedAncestor, 1), + ReactNativePrivateInterface.UIManager.manageChildren( + finishedRoot._nativeTag, + [], + [], + [], + [], + [nearestMountedAncestor] + ))); + break; + case 18: + null !== hostParent && shim(hostParent, deletedFiber.stateNode); + break; + case 4: + prevHostParent = hostParent; + prevHostParentIsContainer = hostParentIsContainer; + hostParent = deletedFiber.stateNode.containerInfo; + hostParentIsContainer = !0; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + hostParent = prevHostParent; + hostParentIsContainer = prevHostParentIsContainer; + break; case 0: case 11: case 14: case 15: - commitHookEffectListUnmount(3, finishedWork, finishedWork.return); - commitHookEffectListMount(3, finishedWork); - commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - return; - case 1: - return; - case 5: - var instance = finishedWork.stateNode; - if (null != instance) { - var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; - var updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; - null !== updatePayload && - ((finishedWork = instance.viewConfig), - instanceProps.set(instance._nativeTag, newProps), - (newProps = diffProperties( - null, - current, - newProps, - finishedWork.validAttributes - )), - null != newProps && - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - finishedWork.uiViewClassName, - newProps - )); + prevHostParent = deletedFiber.updateQueue; + if ( + null !== prevHostParent && + ((prevHostParent = prevHostParent.lastEffect), null !== prevHostParent) + ) { + prevHostParentIsContainer = prevHostParent = prevHostParent.next; + do { + var _effect = prevHostParentIsContainer, + destroy = _effect.destroy; + _effect = _effect.tag; + void 0 !== destroy && + (0 !== (_effect & 2) + ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) + : 0 !== (_effect & 4) && + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + )); + prevHostParentIsContainer = prevHostParentIsContainer.next; + } while (prevHostParentIsContainer !== prevHostParent); } - return; - case 6: - if (null === finishedWork.stateNode) - throw Error( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - ReactNativePrivateInterface.UIManager.updateView( - finishedWork.stateNode, - "RCTRawText", - { text: finishedWork.memoizedProps } + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 1: + safelyDetachRef(deletedFiber, nearestMountedAncestor); + prevHostParent = deletedFiber.stateNode; + if ("function" === typeof prevHostParent.componentWillUnmount) + try { + (prevHostParent.props = deletedFiber.memoizedProps), + (prevHostParent.state = deletedFiber.memoizedState), + prevHostParent.componentWillUnmount(); + } catch (error) { + captureCommitPhaseError(deletedFiber, nearestMountedAncestor, error); + } + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 21: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 22: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + default: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber ); - return; - case 3: - return; - case 12: - return; - case 13: - attachSuspenseRetryListeners(finishedWork); - return; - case 19: - attachSuspenseRetryListeners(finishedWork); - return; - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } function attachSuspenseRetryListeners(finishedWork) { var wakeables = finishedWork.updateQueue; @@ -6010,154 +6113,308 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function commitMutationEffects(root, firstChild) { - for (nextEffect = firstChild; null !== nextEffect; ) { - firstChild = nextEffect; - var deletions = firstChild.deletions; - if (null !== deletions) - for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; - try { - unmountHostComponents(root, childToDelete, firstChild); - var alternate = childToDelete.alternate; - null !== alternate && (alternate.return = null); - childToDelete.return = null; - } catch (error) { - captureCommitPhaseError(childToDelete, firstChild, error); - } - } - deletions = firstChild.child; - if (0 !== (firstChild.subtreeFlags & 12854) && null !== deletions) - (deletions.return = firstChild), (nextEffect = deletions); - else - for (; null !== nextEffect; ) { - firstChild = nextEffect; - try { - var flags = firstChild.flags; - if (flags & 512) { - var current = firstChild.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - if (flags & 8192) - switch (firstChild.tag) { - case 13: - if (null !== firstChild.memoizedState) { - var current$84 = firstChild.alternate; - if (null === current$84 || null === current$84.memoizedState) - globalMostRecentFallbackTime = now(); - } - break; - case 22: - a: { - deletions = firstChild; - var isHidden = null !== firstChild.memoizedState; - i = null; - for (childToDelete = deletions; ; ) { - if (5 === childToDelete.tag) { - if (null === i) { - i = childToDelete; - var instance = childToDelete.stateNode; - if (isHidden) { - var instance$jscomp$0 = instance, - viewConfig = instance$jscomp$0.viewConfig; - var updatePayload = diffProperties( - null, - emptyObject, - { style: { display: "none" } }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance$jscomp$0._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } else { - var instance$jscomp$1 = childToDelete.stateNode, - props = childToDelete.memoizedProps, - viewConfig$jscomp$0 = instance$jscomp$1.viewConfig, - prevProps = assign({}, props, { - style: [props.style, { display: "none" }] - }); - var updatePayload$jscomp$0 = diffProperties( - null, - prevProps, - props, - viewConfig$jscomp$0.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance$jscomp$1._nativeTag, - viewConfig$jscomp$0.uiViewClassName, - updatePayload$jscomp$0 - ); - } - } - } else if (6 === childToDelete.tag) { - if (null === i) throw Error("Not yet implemented."); - } else if ( - ((22 !== childToDelete.tag && 23 !== childToDelete.tag) || - null === childToDelete.memoizedState || - childToDelete === deletions) && - null !== childToDelete.child - ) { - childToDelete.child.return = childToDelete; - childToDelete = childToDelete.child; - continue; - } - if (childToDelete === deletions) break; - for (; null === childToDelete.sibling; ) { - if ( - null === childToDelete.return || - childToDelete.return === deletions - ) - break a; - i === childToDelete && (i = null); - childToDelete = childToDelete.return; - } - i === childToDelete && (i = null); - childToDelete.sibling.return = childToDelete.return; - childToDelete = childToDelete.sibling; - } - } - } - switch (flags & 4102) { - case 2: - commitPlacement(firstChild); - firstChild.flags &= -3; - break; - case 6: - commitPlacement(firstChild); - firstChild.flags &= -3; - commitWork(firstChild.alternate, firstChild); - break; - case 4096: - firstChild.flags &= -4097; - break; - case 4100: - firstChild.flags &= -4097; - commitWork(firstChild.alternate, firstChild); - break; +function recursivelyTraverseMutationEffects(root$jscomp$0, parentFiber) { + var deletions = parentFiber.deletions; + if (null !== deletions) + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; + try { + var root = root$jscomp$0, + returnFiber = parentFiber, + parent = returnFiber; + a: for (; null !== parent; ) { + switch (parent.tag) { + case 5: + hostParent = parent.stateNode; + hostParentIsContainer = !1; + break a; + case 3: + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = !0; + break a; case 4: - commitWork(firstChild.alternate, firstChild); + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = !0; + break a; } - } catch (error) { - captureCommitPhaseError(firstChild, firstChild.return, error); + parent = parent.return; } - deletions = firstChild.sibling; - if (null !== deletions) { - deletions.return = firstChild.return; - nextEffect = deletions; - break; - } - nextEffect = firstChild.return; + if (null === hostParent) + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + commitDeletionEffectsOnFiber(root, returnFiber, childToDelete); + hostParent = null; + hostParentIsContainer = !1; + var alternate = childToDelete.alternate; + null !== alternate && (alternate.return = null); + childToDelete.return = null; + } catch (error) { + captureCommitPhaseError(childToDelete, parentFiber, error); } + } + if (parentFiber.subtreeFlags & 12854) + for (parentFiber = parentFiber.child; null !== parentFiber; ) + commitMutationEffectsOnFiber(parentFiber, root$jscomp$0), + (parentFiber = parentFiber.sibling); +} +function commitMutationEffectsOnFiber(finishedWork, root) { + var current = finishedWork.alternate, + flags = finishedWork.flags; + switch (finishedWork.tag) { + case 0: + case 11: + case 14: + case 15: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & 4) { + try { + commitHookEffectListUnmount(3, finishedWork, finishedWork.return), + commitHookEffectListMount(3, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + try { + commitHookEffectListUnmount(5, finishedWork, finishedWork.return); + } catch (error$83) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$83); + } + } + break; + case 1: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 512 && + null !== current && + safelyDetachRef(current, current.return); + break; + case 5: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 512 && + null !== current && + safelyDetachRef(current, current.return); + if (flags & 4) { + var instance$85 = finishedWork.stateNode; + if (null != instance$85) { + var newProps = finishedWork.memoizedProps, + oldProps = null !== current ? current.memoizedProps : newProps, + updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; + if (null !== updatePayload) + try { + var viewConfig = instance$85.viewConfig; + instanceProps.set(instance$85._nativeTag, newProps); + var updatePayload$jscomp$0 = diffProperties( + null, + oldProps, + newProps, + viewConfig.validAttributes + ); + null != updatePayload$jscomp$0 && + ReactNativePrivateInterface.UIManager.updateView( + instance$85._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } catch (error$86) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error$86 + ); + } + } + } + break; + case 6: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & 4) { + if (null === finishedWork.stateNode) + throw Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ); + viewConfig = finishedWork.stateNode; + updatePayload$jscomp$0 = finishedWork.memoizedProps; + try { + ReactNativePrivateInterface.UIManager.updateView( + viewConfig, + "RCTRawText", + { text: updatePayload$jscomp$0 } + ); + } catch (error$87) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$87); + } + } + break; + case 3: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 4: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 13: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + viewConfig = finishedWork.child; + viewConfig.flags & 8192 && + null !== viewConfig.memoizedState && + (null === viewConfig.alternate || + null === viewConfig.alternate.memoizedState) && + (globalMostRecentFallbackTime = now()); + flags & 4 && attachSuspenseRetryListeners(finishedWork); + break; + case 22: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & 8192) + a: for ( + viewConfig = null !== finishedWork.memoizedState, + updatePayload$jscomp$0 = null, + current = finishedWork; + ; + + ) { + if (5 === current.tag) { + if (null === updatePayload$jscomp$0) { + updatePayload$jscomp$0 = current; + try { + if (((instance$85 = current.stateNode), viewConfig)) + (newProps = instance$85.viewConfig), + (oldProps = diffProperties( + null, + emptyObject, + { style: { display: "none" } }, + newProps.validAttributes + )), + ReactNativePrivateInterface.UIManager.updateView( + instance$85._nativeTag, + newProps.uiViewClassName, + oldProps + ); + else { + updatePayload = current.stateNode; + var props = current.memoizedProps, + viewConfig$jscomp$0 = updatePayload.viewConfig, + prevProps = assign({}, props, { + style: [props.style, { display: "none" }] + }); + var updatePayload$jscomp$1 = diffProperties( + null, + prevProps, + props, + viewConfig$jscomp$0.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig$jscomp$0.uiViewClassName, + updatePayload$jscomp$1 + ); + } + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } else if (6 === current.tag) { + if (null === updatePayload$jscomp$0) + try { + throw Error("Not yet implemented."); + } catch (error$78) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error$78 + ); + } + } else if ( + ((22 !== current.tag && 23 !== current.tag) || + null === current.memoizedState || + current === finishedWork) && + null !== current.child + ) { + current.child.return = current; + current = current.child; + continue; + } + if (current === finishedWork) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === finishedWork) + break a; + updatePayload$jscomp$0 === current && + (updatePayload$jscomp$0 = null); + current = current.return; + } + updatePayload$jscomp$0 === current && (updatePayload$jscomp$0 = null); + current.sibling.return = current.return; + current = current.sibling; + } + break; + case 19: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 4 && attachSuspenseRetryListeners(finishedWork); + break; + case 21: + break; + default: + recursivelyTraverseMutationEffects(root, finishedWork), + commitReconciliationEffects(finishedWork); } } +function commitReconciliationEffects(finishedWork) { + var flags = finishedWork.flags; + if (flags & 2) { + try { + a: { + for (var parent = finishedWork.return; null !== parent; ) { + if (isHostParent(parent)) { + var JSCompiler_inline_result = parent; + break a; + } + parent = parent.return; + } + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + } + switch (JSCompiler_inline_result.tag) { + case 5: + var parent$jscomp$0 = JSCompiler_inline_result.stateNode; + JSCompiler_inline_result.flags & 32 && + (JSCompiler_inline_result.flags &= -33); + var before = getHostSibling(finishedWork); + insertOrAppendPlacementNode(finishedWork, before, parent$jscomp$0); + break; + case 3: + case 4: + var parent$79 = JSCompiler_inline_result.stateNode.containerInfo, + before$80 = getHostSibling(finishedWork); + insertOrAppendPlacementNodeIntoContainer( + finishedWork, + before$80, + parent$79 + ); + break; + default: + throw Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + finishedWork.flags &= -3; + } + flags & 4096 && (finishedWork.flags &= -4097); +} function commitLayoutEffects(finishedWork) { for (nextEffect = finishedWork; null !== nextEffect; ) { var fiber = nextEffect, @@ -6200,8 +6457,8 @@ function commitLayoutEffects(finishedWork) { commitUpdateQueue(firstChild, updateQueue, instance); break; case 3: - var updateQueue$78 = firstChild.updateQueue; - if (null !== updateQueue$78) { + var updateQueue$74 = firstChild.updateQueue; + if (null !== updateQueue$74) { current = null; if (null !== firstChild.child) switch (firstChild.child.tag) { @@ -6211,7 +6468,7 @@ function commitLayoutEffects(finishedWork) { case 1: current = firstChild.child.stateNode; } - commitUpdateQueue(firstChild, updateQueue$78, current); + commitUpdateQueue(firstChild, updateQueue$74, current); } break; case 5: @@ -6229,6 +6486,7 @@ function commitLayoutEffects(finishedWork) { case 21: case 22: case 23: + case 25: break; default: throw Error( @@ -6289,6 +6547,7 @@ var ceil = Math.ceil, workInProgressRootRecoverableErrors = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, + workInProgressTransitions = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -6313,10 +6572,7 @@ function requestUpdateLane(fiber) { if (null !== ReactCurrentBatchConfig.transition) return ( 0 === currentEventTransitionLane && - ((fiber = nextTransitionLane), - (nextTransitionLane <<= 1), - 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64), - (currentEventTransitionLane = fiber)), + (currentEventTransitionLane = claimNextTransitionLane()), currentEventTransitionLane ); fiber = currentUpdatePriority; @@ -6359,6 +6615,13 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { (sourceFiber = sourceFiber.return); return 3 === alternate.tag ? alternate.stateNode : null; } +function isInterleavedUpdate(fiber) { + return ( + (null !== workInProgressRoot || null !== interleavedQueues) && + 0 !== (fiber.mode & 1) && + 0 === (executionContext & 2) + ); +} function ensureRootIsScheduled(root, currentTime) { for ( var existingCallbackNode = root.callbackNode, @@ -6454,7 +6717,8 @@ function performConcurrentWorkOnRoot(root, didTimeout) { workInProgressRoot !== root || workInProgressRootRenderLanes !== didTimeout ) - (workInProgressRootRenderTargetTime = now() + 500), + (workInProgressTransitions = null), + (workInProgressRootRenderTargetTime = now() + 500), prepareFreshStack(root, didTimeout); do try { @@ -6511,7 +6775,11 @@ function performConcurrentWorkOnRoot(root, didTimeout) { case 1: throw Error("Root did not complete. This is a bug in React."); case 2: - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 3: markRootSuspended$1(root, lanes); @@ -6528,12 +6796,21 @@ function performConcurrentWorkOnRoot(root, didTimeout) { break; } root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), didTimeout ); break; } - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 4: markRootSuspended$1(root, lanes); @@ -6564,15 +6841,28 @@ function performConcurrentWorkOnRoot(root, didTimeout) { : 1960 * ceil(lanes / 1960)) - lanes; if (10 < lanes) { root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), lanes ); break; } - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 5: - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; default: throw Error("Unknown root exit status."); @@ -6592,15 +6882,17 @@ function recoverFromConcurrentError(root, errorRetryLanes) { 2 !== root && ((errorRetryLanes = workInProgressRootRecoverableErrors), (workInProgressRootRecoverableErrors = errorsFromFirstAttempt), - null !== errorRetryLanes && - (null === workInProgressRootRecoverableErrors - ? (workInProgressRootRecoverableErrors = errorRetryLanes) - : workInProgressRootRecoverableErrors.push.apply( - workInProgressRootRecoverableErrors, - errorRetryLanes - ))); + null !== errorRetryLanes && queueRecoverableErrors(errorRetryLanes)); return root; } +function queueRecoverableErrors(errors) { + null === workInProgressRootRecoverableErrors + ? (workInProgressRootRecoverableErrors = errors) + : workInProgressRootRecoverableErrors.push.apply( + workInProgressRootRecoverableErrors, + errors + ); +} function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { if (node.flags & 16384) { @@ -6670,7 +6962,11 @@ function performSyncWorkOnRoot(root) { throw Error("Root did not complete. This is a bug in React."); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); ensureRootIsScheduled(root, now()); return null; } @@ -6906,12 +7202,12 @@ function handleError(root$jscomp$0, thrownValue) { root.flags |= 65536; thrownValue &= -thrownValue; root.lanes |= thrownValue; - var update$33 = createClassErrorUpdate( + var update$34 = createClassErrorUpdate( root, wakeable, thrownValue ); - enqueueCapturedUpdate(root, update$33); + enqueueCapturedUpdate(root, update$34); break a; } } @@ -6950,8 +7246,8 @@ function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 2; var prevDispatcher = pushDispatcher(); - (workInProgressRoot === root && workInProgressRootRenderLanes === lanes) || - prepareFreshStack(root, lanes); + if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) + (workInProgressTransitions = null), prepareFreshStack(root, lanes); do try { workLoopSync(); @@ -7023,50 +7319,60 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors) { +function commitRoot(root, recoverableErrors, transitions) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$2.transition; try { (ReactCurrentBatchConfig$2.transition = null), (currentUpdatePriority = 1), - commitRootImpl(root, recoverableErrors, previousUpdateLanePriority); + commitRootImpl( + root, + recoverableErrors, + transitions, + previousUpdateLanePriority + ); } finally { (ReactCurrentBatchConfig$2.transition = prevTransition), (currentUpdatePriority = previousUpdateLanePriority); } return null; } -function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { +function commitRootImpl( + root, + recoverableErrors, + transitions, + renderPriorityLevel +) { do flushPassiveEffects(); while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 6)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - if (null === finishedWork) return null; + transitions = root.finishedWork; + var lanes = root.finishedLanes; + if (null === transitions) return null; root.finishedWork = null; root.finishedLanes = 0; - if (finishedWork === root.current) + if (transitions === root.current) throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; root.callbackPriority = 0; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + var remainingLanes = transitions.lanes | transitions.childLanes; markRootFinished(root, remainingLanes); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 2064) && - 0 === (finishedWork.flags & 2064)) || + (0 === (transitions.subtreeFlags & 2064) && + 0 === (transitions.flags & 2064)) || rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), scheduleCallback$1(NormalPriority, function() { flushPassiveEffects(); return null; })); - remainingLanes = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || remainingLanes) { + remainingLanes = 0 !== (transitions.flags & 15990); + if (0 !== (transitions.subtreeFlags & 15990) || remainingLanes) { remainingLanes = ReactCurrentBatchConfig$2.transition; ReactCurrentBatchConfig$2.transition = null; var previousPriority = currentUpdatePriority; @@ -7074,30 +7380,30 @@ function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { var prevExecutionContext = executionContext; executionContext |= 4; ReactCurrentOwner$2.current = null; - commitBeforeMutationEffects(root, finishedWork); - commitMutationEffects(root, finishedWork, lanes); - root.current = finishedWork; - commitLayoutEffects(finishedWork, root, lanes); + commitBeforeMutationEffects(root, transitions); + commitMutationEffectsOnFiber(transitions, root); + root.current = transitions; + commitLayoutEffects(transitions, root, lanes); requestPaint(); executionContext = prevExecutionContext; currentUpdatePriority = previousPriority; ReactCurrentBatchConfig$2.transition = remainingLanes; - } else root.current = finishedWork; + } else root.current = transitions; rootDoesHavePassiveEffects && ((rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + onCommitRoot(transitions.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (null !== recoverableErrors) for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ + renderPriorityLevel = root.onRecoverableError, transitions = 0; + transitions < recoverableErrors.length; + transitions++ ) - renderPriorityLevel(recoverableErrors[finishedWork]); + renderPriorityLevel(recoverableErrors[transitions]); if (hasUncaughtError) throw ((hasUncaughtError = !1), (root = firstUncaughtError), @@ -7332,21 +7638,43 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { : (workInProgressRootPingedLanes |= pingedLanes)); ensureRootIsScheduled(root, wakeable); } -function resolveRetryWakeable(boundaryFiber, wakeable) { - var retryCache = boundaryFiber.stateNode; - null !== retryCache && retryCache.delete(wakeable); - wakeable = 0; - 0 === wakeable && +function retryTimedOutBoundary(boundaryFiber, retryLane) { + 0 === retryLane && (0 === (boundaryFiber.mode & 1) - ? (wakeable = 1) - : ((wakeable = nextRetryLane), + ? (retryLane = 1) + : ((retryLane = nextRetryLane), (nextRetryLane <<= 1), 0 === (nextRetryLane & 130023424) && (nextRetryLane = 4194304))); - retryCache = requestEventTime(); - boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); + var eventTime = requestEventTime(); + boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane); null !== boundaryFiber && - (markRootUpdated(boundaryFiber, wakeable, retryCache), - ensureRootIsScheduled(boundaryFiber, retryCache)); + (markRootUpdated(boundaryFiber, retryLane, eventTime), + ensureRootIsScheduled(boundaryFiber, eventTime)); +} +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState, + retryLane = 0; + null !== suspenseState && (retryLane = suspenseState.retryLane); + retryTimedOutBoundary(boundaryFiber, retryLane); +} +function resolveRetryWakeable(boundaryFiber, wakeable) { + var retryLane = 0; + switch (boundaryFiber.tag) { + case 13: + var retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + null !== suspenseState && (retryLane = suspenseState.retryLane); + break; + case 19: + retryCache = boundaryFiber.stateNode; + break; + default: + throw Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ); + } + null !== retryCache && retryCache.delete(wakeable); + retryTimedOutBoundary(boundaryFiber, retryLane); } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { @@ -7376,10 +7704,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { switch (workInProgress.tag) { case 2: var Component = workInProgress.type; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; var context = getMaskedContext( workInProgress, @@ -7433,10 +7758,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 16: Component = workInProgress.elementType; a: { - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; context = Component._init; Component = context(Component._payload); @@ -7542,7 +7864,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return ( pushHostContext(workInProgress), (Component = workInProgress.pendingProps.children), - markRef$1(current, workInProgress), + markRef(current, workInProgress), reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); @@ -7636,24 +7958,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - newValue = workInProgress.child, - null !== newValue && (newValue.return = workInProgress); - null !== newValue; + hasContext = workInProgress.child, + null !== hasContext && (hasContext.return = workInProgress); + null !== hasContext; ) { - var list = newValue.dependencies; + var list = hasContext.dependencies; if (null !== list) { - hasContext = newValue.child; + newValue = hasContext.child; for ( var dependency = list.firstContext; null !== dependency; ) { if (dependency.context === Component) { - if (1 === newValue.tag) { + if (1 === hasContext.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; - var updateQueue = newValue.updateQueue; + var updateQueue = hasContext.updateQueue; if (null !== updateQueue) { updateQueue = updateQueue.shared; var pending = updateQueue.pending; @@ -7664,11 +7986,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateQueue.pending = dependency; } } - newValue.lanes |= renderLanes; - dependency = newValue.alternate; + hasContext.lanes |= renderLanes; + dependency = hasContext.alternate; null !== dependency && (dependency.lanes |= renderLanes); scheduleContextWorkOnParentPath( - newValue.return, + hasContext.return, renderLanes, workInProgress ); @@ -7677,29 +7999,43 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } dependency = dependency.next; } - } else - hasContext = - 10 === newValue.tag - ? newValue.type === workInProgress.type - ? null - : newValue.child - : newValue.child; - if (null !== hasContext) hasContext.return = newValue; + } else if (10 === hasContext.tag) + newValue = + hasContext.type === workInProgress.type + ? null + : hasContext.child; + else if (18 === hasContext.tag) { + newValue = hasContext.return; + if (null === newValue) + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + newValue.lanes |= renderLanes; + list = newValue.alternate; + null !== list && (list.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + newValue, + renderLanes, + workInProgress + ); + newValue = hasContext.sibling; + } else newValue = hasContext.child; + if (null !== newValue) newValue.return = hasContext; else - for (hasContext = newValue; null !== hasContext; ) { - if (hasContext === workInProgress) { - hasContext = null; + for (newValue = hasContext; null !== newValue; ) { + if (newValue === workInProgress) { + newValue = null; break; } - newValue = hasContext.sibling; - if (null !== newValue) { - newValue.return = hasContext.return; - hasContext = newValue; + hasContext = newValue.sibling; + if (null !== hasContext) { + hasContext.return = newValue.return; + newValue = hasContext; break; } - hasContext = hasContext.return; + newValue = newValue.return; } - newValue = hasContext; + hasContext = newValue; } reconcileChildren( current, @@ -7750,10 +8086,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress.elementType === Component ? context : resolveDefaultProps(Component, context)), - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)), + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), (workInProgress.tag = 1), isContextProvider(Component) ? ((current = !0), pushContextProvider(workInProgress)) @@ -8100,10 +8433,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_963 = { + devToolsConfig$jscomp$inline_967 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "18.0.0-experimental-34aa5cfe0-20220329", + version: "18.2.0-next-d300cebde-20220601", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8118,11 +8451,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1217 = { - bundleType: devToolsConfig$jscomp$inline_963.bundleType, - version: devToolsConfig$jscomp$inline_963.version, - rendererPackageName: devToolsConfig$jscomp$inline_963.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_963.rendererConfig, +var internals$jscomp$inline_1239 = { + bundleType: devToolsConfig$jscomp$inline_967.bundleType, + version: devToolsConfig$jscomp$inline_967.version, + rendererPackageName: devToolsConfig$jscomp$inline_967.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_967.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8138,26 +8471,26 @@ var internals$jscomp$inline_1217 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_963.findFiberByHostInstance || + devToolsConfig$jscomp$inline_967.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.0.0-experimental-34aa5cfe0-20220329" + reconcilerVersion: "18.2.0-next-d300cebde-20220601" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1218 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1240 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1218.isDisabled && - hook$jscomp$inline_1218.supportsFiber + !hook$jscomp$inline_1240.isDisabled && + hook$jscomp$inline_1240.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1218.inject( - internals$jscomp$inline_1217 + (rendererID = hook$jscomp$inline_1240.inject( + internals$jscomp$inline_1239 )), - (injectedHook = hook$jscomp$inline_1218); + (injectedHook = hook$jscomp$inline_1240); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -8212,7 +8545,8 @@ exports.render = function(element, containerTag, callback) { element: null, isDehydrated: !1, cache: null, - transitions: null + transitions: null, + pendingSuspenseBoundaries: null }; initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js index 917bd003a1c..3a9a2679c42 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactNativeRenderer-profiling * @preventMunge - * @generated SignedSource<<06200cf762f5eb0f48046de454a64107>> + * @generated SignedSource<<2bf865cebf1e47b3fc0284498b4571db>> */ @@ -1028,7 +1028,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_228 = { +var injectedNamesToPlugins$jscomp$inline_236 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1074,33 +1074,33 @@ var injectedNamesToPlugins$jscomp$inline_228 = { } } }, - isOrderingDirty$jscomp$inline_229 = !1, - pluginName$jscomp$inline_230; -for (pluginName$jscomp$inline_230 in injectedNamesToPlugins$jscomp$inline_228) + isOrderingDirty$jscomp$inline_237 = !1, + pluginName$jscomp$inline_238; +for (pluginName$jscomp$inline_238 in injectedNamesToPlugins$jscomp$inline_236) if ( - injectedNamesToPlugins$jscomp$inline_228.hasOwnProperty( - pluginName$jscomp$inline_230 + injectedNamesToPlugins$jscomp$inline_236.hasOwnProperty( + pluginName$jscomp$inline_238 ) ) { - var pluginModule$jscomp$inline_231 = - injectedNamesToPlugins$jscomp$inline_228[pluginName$jscomp$inline_230]; + var pluginModule$jscomp$inline_239 = + injectedNamesToPlugins$jscomp$inline_236[pluginName$jscomp$inline_238]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_230) || - namesToPlugins[pluginName$jscomp$inline_230] !== - pluginModule$jscomp$inline_231 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_238) || + namesToPlugins[pluginName$jscomp$inline_238] !== + pluginModule$jscomp$inline_239 ) { - if (namesToPlugins[pluginName$jscomp$inline_230]) + if (namesToPlugins[pluginName$jscomp$inline_238]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_230 + "`.") + (pluginName$jscomp$inline_238 + "`.") ); namesToPlugins[ - pluginName$jscomp$inline_230 - ] = pluginModule$jscomp$inline_231; - isOrderingDirty$jscomp$inline_229 = !0; + pluginName$jscomp$inline_238 + ] = pluginModule$jscomp$inline_239; + isOrderingDirty$jscomp$inline_237 = !0; } } -isOrderingDirty$jscomp$inline_229 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_237 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1952,6 +1952,12 @@ function getLanesToRetrySynchronouslyOnError(root) { root = root.pendingLanes & -1073741825; return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; } +function claimNextTransitionLane() { + var lane = nextTransitionLane; + nextTransitionLane <<= 1; + 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64); + return lane; +} function createLaneMap(initial) { for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); return laneMap; @@ -2211,7 +2217,28 @@ function flushSyncCallbacks() { } return null; } -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +var forkStack = [], + forkStackIndex = 0, + treeForkProvider = null, + idStack = [], + idStackIndex = 0, + treeContextProvider = null; +function popTreeContext(workInProgress) { + for (; workInProgress === treeForkProvider; ) + (treeForkProvider = forkStack[--forkStackIndex]), + (forkStack[forkStackIndex] = null), + --forkStackIndex, + (forkStack[forkStackIndex] = null); + for (; workInProgress === treeContextProvider; ) + (treeContextProvider = idStack[--idStackIndex]), + (idStack[idStackIndex] = null), + --idStackIndex, + (idStack[idStackIndex] = null), + --idStackIndex, + (idStack[idStackIndex] = null); +} +var hydrationErrors = null, + ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function shallowEqual(objA, objB) { if (objectIs(objA, objB)) return !0; if ( @@ -2368,9 +2395,7 @@ function enqueueUpdate(fiber, update) { var updateQueue = fiber.updateQueue; null !== updateQueue && ((updateQueue = updateQueue.shared), - null !== workInProgressRoot && - 0 !== (fiber.mode & 1) && - 0 === (executionContext & 2) + isInterleavedUpdate(fiber) ? ((fiber = updateQueue.interleaved), null === fiber ? ((update.next = update), @@ -2738,26 +2763,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var forkStack = [], - forkStackIndex = 0, - treeForkProvider = null, - idStack = [], - idStackIndex = 0, - treeContextProvider = null; -function popTreeContext(workInProgress) { - for (; workInProgress === treeForkProvider; ) - (treeForkProvider = forkStack[--forkStackIndex]), - (forkStack[forkStackIndex] = null), - --forkStackIndex, - (forkStack[forkStackIndex] = null); - for (; workInProgress === treeContextProvider; ) - (treeContextProvider = idStack[--idStackIndex]), - (idStack[idStackIndex] = null), - --idStackIndex, - (idStack[idStackIndex] = null), - --idStackIndex, - (idStack[idStackIndex] = null); -} function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2820,6 +2825,10 @@ function throwOnInvalidObjectType(returnFiber, newChild) { "). If you meant to render a collection of children, use an array instead." ); } +function resolveLazy(lazyType) { + var init = lazyType._init; + return init(lazyType._payload); +} function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { @@ -2892,7 +2901,14 @@ function ChildReconciler(shouldTrackSideEffects) { lanes, element.key ); - if (null !== current && current.elementType === elementType) + if ( + null !== current && + (current.elementType === elementType || + ("object" === typeof elementType && + null !== elementType && + elementType.$$typeof === REACT_LAZY_TYPE && + resolveLazy(elementType) === current.type)) + ) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2983,6 +2999,9 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild.return = returnFiber), newChild ); + case REACT_LAZY_TYPE: + var init = newChild._init; + return createChild(returnFiber, init(newChild._payload), lanes); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -3018,6 +3037,11 @@ function ChildReconciler(shouldTrackSideEffects) { return newChild.key === key ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; + case REACT_LAZY_TYPE: + return ( + (key = newChild._init), + updateSlot(returnFiber, oldFiber, key(newChild._payload), lanes) + ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key @@ -3060,6 +3084,15 @@ function ChildReconciler(shouldTrackSideEffects) { ) || null), updatePortal(returnFiber, existingChildren, newChild, lanes) ); + case REACT_LAZY_TYPE: + var init = newChild._init; + return updateFromMap( + existingChildren, + returnFiber, + newIdx, + init(newChild._payload), + lanes + ); } if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( @@ -3237,7 +3270,12 @@ function ChildReconciler(shouldTrackSideEffects) { }); return iteratorFn; } - return function(returnFiber, currentFirstChild, newChild, lanes) { + function reconcileChildFibers( + returnFiber, + currentFirstChild, + newChild, + lanes + ) { "object" === typeof newChild && null !== newChild && newChild.type === REACT_FRAGMENT_TYPE && @@ -3265,7 +3303,13 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; break a; } - } else if (child.elementType === key) { + } else if ( + child.elementType === key || + ("object" === typeof key && + null !== key && + key.$$typeof === REACT_LAZY_TYPE && + resolveLazy(key) === child.type) + ) { deleteRemainingChildren(returnFiber, child.sibling); currentFirstChild = useFiber(child, newChild.props); currentFirstChild.ref = coerceRef( @@ -3346,6 +3390,16 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; } return placeSingleChild(returnFiber); + case REACT_LAZY_TYPE: + return ( + (child = newChild._init), + reconcileChildFibers( + returnFiber, + currentFirstChild, + child(newChild._payload), + lanes + ) + ); } if (isArrayImpl(newChild)) return reconcileChildrenArray( @@ -3381,7 +3435,8 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber)) : deleteRemainingChildren(returnFiber, currentFirstChild); - }; + } + return reconcileChildFibers; } var reconcileChildFibers = ChildReconciler(!0), mountChildFibers = ChildReconciler(!1), @@ -3868,6 +3923,19 @@ function updateMemo(nextCreate, deps) { hook.memoizedState = [nextCreate, deps]; return nextCreate; } +function updateDeferredValueImpl(hook, prevValue, value) { + if (0 === (renderLanes & 21)) + return ( + hook.baseState && ((hook.baseState = !1), (didReceiveUpdate = !0)), + (hook.memoizedState = value) + ); + objectIs(value, prevValue) || + ((value = claimNextTransitionLane()), + (currentlyRenderingFiber$1.lanes |= value), + (workInProgressRootSkippedLanes |= value), + (hook.baseState = !0)); + return prevValue; +} function startTransition(setPending, callback) { var previousPriority = currentUpdatePriority; currentUpdatePriority = @@ -3949,9 +4017,7 @@ function enqueueRenderPhaseUpdate(queue, update) { queue.pending = update; } function enqueueUpdate$1(fiber, queue, update) { - null !== workInProgressRoot && - 0 !== (fiber.mode & 1) && - 0 === (executionContext & 2) + isInterleavedUpdate(fiber) ? ((fiber = queue.interleaved), null === fiber ? ((update.next = update), @@ -4056,29 +4122,14 @@ var ContextOnlyDispatcher = { useState: mountState, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _mountState = mountState(value), - prevValue = _mountState[0], - setValue = _mountState[1]; - mountEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + return (mountWorkInProgressHook().memoizedState = value); }, useTransition: function() { - var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = startTransition.bind(null, _mountState2[1]); - mountWorkInProgressHook().memoizedState = _mountState2; - return [isPending, _mountState2]; + var _mountState = mountState(!1), + isPending = _mountState[0]; + _mountState = startTransition.bind(null, _mountState[1]); + mountWorkInProgressHook().memoizedState = _mountState; + return [isPending, _mountState]; }, useMutableSource: function() {}, useSyncExternalStore: function(subscribe, getSnapshot) { @@ -4132,22 +4183,8 @@ var ContextOnlyDispatcher = { }, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _updateState = updateReducer(basicStateReducer), - prevValue = _updateState[0], - setValue = _updateState[1]; - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + return updateDeferredValueImpl(hook, currentHook.memoizedState, value); }, useTransition: function() { var isPending = updateReducer(basicStateReducer)[0], @@ -4175,22 +4212,10 @@ var ContextOnlyDispatcher = { }, useDebugValue: mountDebugValue, useDeferredValue: function(value) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - updateEffect( - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = {}; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }, - [value] - ); - return prevValue; + var hook = updateWorkInProgressHook(); + return null === currentHook + ? (hook.memoizedState = value) + : updateDeferredValueImpl(hook, currentHook.memoizedState, value); }, useTransition: function() { var isPending = rerenderReducer(basicStateReducer)[0], @@ -4346,437 +4371,6 @@ function attachPingListener(root, wakeable, lanes) { isDevToolsPresent && restorePendingUpdaters(root, lanes), wakeable.then(pingCache, pingCache)); } -var appendAllChildren, updateHostContainer, updateHostComponent, updateHostText; -appendAllChildren = function(parent, workInProgress) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); - else if (4 !== node.tag && null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -}; -updateHostContainer = function() {}; -updateHostComponent = function(current, workInProgress, type, newProps) { - current.memoizedProps !== newProps && - (requiredContext(contextStackCursor$1.current), - (workInProgress.updateQueue = UPDATE_SIGNAL)) && - (workInProgress.flags |= 4); -}; -updateHostText = function(current, workInProgress, oldText, newText) { - oldText !== newText && (workInProgress.flags |= 4); -}; -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var lastTailNode$37 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$37 = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === lastTailNode$37 - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (lastTailNode$37.sibling = null); - } -} -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - if (0 !== (completedWork.mode & 2)) { - for ( - var treeBaseDuration$39 = completedWork.selfBaseDuration, - child$40 = completedWork.child; - null !== child$40; - - ) - (newChildLanes |= child$40.lanes | child$40.childLanes), - (subtreeFlags |= child$40.subtreeFlags & 14680064), - (subtreeFlags |= child$40.flags & 14680064), - (treeBaseDuration$39 += child$40.treeBaseDuration), - (child$40 = child$40.sibling); - completedWork.treeBaseDuration = treeBaseDuration$39; - } else - for ( - treeBaseDuration$39 = completedWork.child; - null !== treeBaseDuration$39; - - ) - (newChildLanes |= - treeBaseDuration$39.lanes | treeBaseDuration$39.childLanes), - (subtreeFlags |= treeBaseDuration$39.subtreeFlags & 14680064), - (subtreeFlags |= treeBaseDuration$39.flags & 14680064), - (treeBaseDuration$39.return = completedWork), - (treeBaseDuration$39 = treeBaseDuration$39.sibling); - else if (0 !== (completedWork.mode & 2)) { - treeBaseDuration$39 = completedWork.actualDuration; - child$40 = completedWork.selfBaseDuration; - for (var child = completedWork.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (subtreeFlags |= child.subtreeFlags), - (subtreeFlags |= child.flags), - (treeBaseDuration$39 += child.actualDuration), - (child$40 += child.treeBaseDuration), - (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$39; - completedWork.treeBaseDuration = child$40; - } else - for ( - treeBaseDuration$39 = completedWork.child; - null !== treeBaseDuration$39; - - ) - (newChildLanes |= - treeBaseDuration$39.lanes | treeBaseDuration$39.childLanes), - (subtreeFlags |= treeBaseDuration$39.subtreeFlags), - (subtreeFlags |= treeBaseDuration$39.flags), - (treeBaseDuration$39.return = completedWork), - (treeBaseDuration$39 = treeBaseDuration$39.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; - popTreeContext(workInProgress); - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); - case 3: - return ( - (newProps = workInProgress.stateNode), - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - resetWorkInProgressVersions(), - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)), - (null !== current && null !== current.child) || - null === current || - (current.memoizedState.isDehydrated && - 0 === (workInProgress.flags & 256)) || - (workInProgress.flags |= 1024), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 5: - popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent( - current, - workInProgress, - type, - newProps, - renderLanes - ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 512); - else { - if (!newProps) { - if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - bubbleProperties(workInProgress); - return null; - } - requiredContext(contextStackCursor$1.current); - current = allocateTag(); - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - ReactNativePrivateInterface.UIManager.createView( - current, - type.uiViewClassName, - renderLanes, - updatePayload - ); - renderLanes = new ReactNativeFiberHostComponent( - current, - type, - workInProgress - ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - appendAllChildren(renderLanes, workInProgress, !1, !1); - workInProgress.stateNode = renderLanes; - finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 512); - } - bubbleProperties(workInProgress); - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - if (!requiredContext(contextStackCursor$1.current).isInAParentText) - throw Error( - "Text strings must be rendered within a component." - ); - renderLanes = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - renderLanes, - "RCTRawText", - current, - { text: newProps } - ); - instanceCache.set(renderLanes, workInProgress); - workInProgress.stateNode = renderLanes; - } - bubbleProperties(workInProgress); - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) - return ( - (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress - ); - newProps = null !== newProps; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - newProps && - !renderLanes && - ((workInProgress.child.flags |= 8192), - 0 !== (workInProgress.mode & 1) && - (null === current || 0 !== (suspenseStackCursor.current & 1) - ? 0 === workInProgressRootExitStatus && - (workInProgressRootExitStatus = 3) - : renderDidSuspendDelayIfPossible())); - null !== workInProgress.updateQueue && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 2) && - newProps && - ((current = workInProgress.child), - null !== current && - (workInProgress.treeBaseDuration -= current.treeBaseDuration)); - return null; - case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); - case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); - case 19: - pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; - if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); - else { - if ( - 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (updatePayload = current), - (renderLanes.flags &= 14680066), - (type = renderLanes.alternate), - null === type - ? ((renderLanes.childLanes = 0), - (renderLanes.lanes = updatePayload), - (renderLanes.child = null), - (renderLanes.subtreeFlags = 0), - (renderLanes.memoizedProps = null), - (renderLanes.memoizedState = null), - (renderLanes.updateQueue = null), - (renderLanes.dependencies = null), - (renderLanes.stateNode = null), - (renderLanes.selfBaseDuration = 0), - (renderLanes.treeBaseDuration = 0)) - : ((renderLanes.childLanes = type.childLanes), - (renderLanes.lanes = type.lanes), - (renderLanes.child = type.child), - (renderLanes.subtreeFlags = 0), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = type.memoizedProps), - (renderLanes.memoizedState = type.memoizedState), - (renderLanes.updateQueue = type.updateQueue), - (renderLanes.type = type.type), - (updatePayload = type.dependencies), - (renderLanes.dependencies = - null === updatePayload - ? null - : { - lanes: updatePayload.lanes, - firstContext: updatePayload.firstContext - }), - (renderLanes.selfBaseDuration = type.selfBaseDuration), - (renderLanes.treeBaseDuration = type.treeBaseDuration)), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== type.tail && - now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && - !updatePayload.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now() - type.renderingStartTime > - workInProgressRootRenderTargetTime && - 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - type.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (type.last = updatePayload)); - } - if (null !== type.tail) - return ( - (workInProgress = type.tail), - (type.rendering = workInProgress), - (type.tail = workInProgress.sibling), - (type.renderingStartTime = now()), - (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), - workInProgress - ); - bubbleProperties(workInProgress); - return null; - case 22: - case 23: - return ( - popRenderLanes(), - (newProps = null !== workInProgress.memoizedState), - null !== current && - (null !== current.memoizedState) !== newProps && - (workInProgress.flags |= 8192), - newProps && 0 !== (workInProgress.mode & 1) - ? 0 !== (subtreeRenderLanes & 1073741824) && - (bubbleProperties(workInProgress), - workInProgress.subtreeFlags & 6 && (workInProgress.flags |= 8192)) - : bubbleProperties(workInProgress), - null - ); - case 24: - return null; - case 25: - return null; - } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); -} var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { @@ -4879,18 +4473,24 @@ function updateSimpleMemoComponent( nextProps, renderLanes ) { - if ( - null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes))) - 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); - else - return ( - (workInProgress.lanes = current.lanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); + if (null !== current) { + var prevProps = current.memoizedProps; + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref + ) + if ( + ((didReceiveUpdate = !1), + (workInProgress.pendingProps = nextProps = prevProps), + 0 !== (current.lanes & renderLanes)) + ) + 0 !== (current.flags & 131072) && (didReceiveUpdate = !0); + else + return ( + (workInProgress.lanes = current.lanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + } return updateFunctionComponent( current, workInProgress, @@ -4905,7 +4505,11 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { prevState = null !== current ? current.memoizedState : null; if ("hidden" === nextProps.mode) if (0 === (workInProgress.mode & 1)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + (workInProgress.memoizedState = { + baseLanes: 0, + cachePool: null, + transitions: null + }), push(subtreeRenderLanesCursor, subtreeRenderLanes), (subtreeRenderLanes |= renderLanes); else { @@ -4918,14 +4522,19 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { (workInProgress.lanes = workInProgress.childLanes = 1073741824), (workInProgress.memoizedState = { baseLanes: current, - cachePool: null + cachePool: null, + transitions: null }), (workInProgress.updateQueue = null), push(subtreeRenderLanesCursor, subtreeRenderLanes), (subtreeRenderLanes |= current), null ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + workInProgress.memoizedState = { + baseLanes: 0, + cachePool: null, + transitions: null + }; nextProps = null !== prevState ? prevState.baseLanes : renderLanes; push(subtreeRenderLanesCursor, subtreeRenderLanes); subtreeRenderLanes |= nextProps; @@ -4940,7 +4549,7 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef$1(current, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( (null === current && null !== ref) || @@ -4992,10 +4601,7 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderLanes); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)), + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), constructClassInstance(workInProgress, Component, nextProps), mountClassInstance(workInProgress, Component, nextProps, renderLanes), (nextProps = !0); @@ -5189,7 +4795,7 @@ function finishClassComponent( hasContext, renderLanes ) { - markRef$1(current, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( @@ -5239,14 +4845,15 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, treeContext: null, retryLane: 0 }; function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: null }; + return { baseLanes: renderLanes, cachePool: null, transitions: null }; } function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, + didSuspend = 0 !== (workInProgress.flags & 128), JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || + (JSCompiler_temp = didSuspend) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 @@ -5256,177 +4863,307 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext |= 1; push(suspenseStackCursor, suspenseContext & 1); if (null === current) { - suspenseContext = nextProps.children; - current = nextProps.fallback; - if (showFallback) + current = workInProgress.memoizedState; + if (null !== current && null !== current.dehydrated) return ( - (showFallback = workInProgress.mode), - (nextProps = workInProgress.child), - (suspenseContext = { mode: "hidden", children: suspenseContext }), - 0 === (showFallback & 1) && null !== nextProps - ? ((nextProps.childLanes = 0), - (nextProps.pendingProps = suspenseContext), + 0 === (workInProgress.mode & 1) + ? (workInProgress.lanes = 1) + : shim() + ? (workInProgress.lanes = 8) + : (workInProgress.lanes = 1073741824), + null + ); + didSuspend = nextProps.children; + current = nextProps.fallback; + return showFallback + ? ((nextProps = workInProgress.mode), + (showFallback = workInProgress.child), + (didSuspend = { mode: "hidden", children: didSuspend }), + 0 === (nextProps & 1) && null !== showFallback + ? ((showFallback.childLanes = 0), + (showFallback.pendingProps = didSuspend), workInProgress.mode & 2 && - ((nextProps.actualDuration = 0), - (nextProps.actualStartTime = -1), - (nextProps.selfBaseDuration = 0), - (nextProps.treeBaseDuration = 0))) - : (nextProps = createFiberFromOffscreen( - suspenseContext, - showFallback, + ((showFallback.actualDuration = 0), + (showFallback.actualStartTime = -1), + (showFallback.selfBaseDuration = 0), + (showFallback.treeBaseDuration = 0))) + : (showFallback = createFiberFromOffscreen( + didSuspend, + nextProps, 0, null )), (current = createFiberFromFragment( current, - showFallback, + nextProps, renderLanes, null )), - (nextProps.return = workInProgress), + (showFallback.return = workInProgress), (current.return = workInProgress), - (nextProps.sibling = current), - (workInProgress.child = nextProps), + (showFallback.sibling = current), + (workInProgress.child = showFallback), (workInProgress.child.memoizedState = mountSuspenseOffscreenState( renderLanes )), (workInProgress.memoizedState = SUSPENDED_MARKER), - current - ); - renderLanes = createFiberFromOffscreen( - { mode: "visible", children: suspenseContext }, - workInProgress.mode, - 0, - null - ); - renderLanes.return = workInProgress; - return (workInProgress.child = renderLanes); + current) + : mountSuspensePrimaryChildren(workInProgress, didSuspend); } - if (null !== current.memoizedState) { - if (showFallback) - return ( - (showFallback = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (nextProps = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (nextProps.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (nextProps.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - showFallback - ); - renderLanes = updateSuspensePrimaryChildren( + suspenseContext = current.memoizedState; + if ( + null !== suspenseContext && + ((JSCompiler_temp = suspenseContext.dehydrated), null !== JSCompiler_temp) + ) + return updateDehydratedSuspenseComponent( current, workInProgress, - nextProps.children, + didSuspend, + nextProps, + JSCompiler_temp, + suspenseContext, renderLanes ); - workInProgress.memoizedState = null; - return renderLanes; + if (showFallback) { + showFallback = nextProps.fallback; + didSuspend = workInProgress.mode; + suspenseContext = current.child; + JSCompiler_temp = suspenseContext.sibling; + var primaryChildProps = { mode: "hidden", children: nextProps.children }; + 0 === (didSuspend & 1) && workInProgress.child !== suspenseContext + ? ((nextProps = workInProgress.child), + (nextProps.childLanes = 0), + (nextProps.pendingProps = primaryChildProps), + workInProgress.mode & 2 && + ((nextProps.actualDuration = 0), + (nextProps.actualStartTime = -1), + (nextProps.selfBaseDuration = suspenseContext.selfBaseDuration), + (nextProps.treeBaseDuration = suspenseContext.treeBaseDuration)), + (workInProgress.deletions = null)) + : ((nextProps = createWorkInProgress(suspenseContext, primaryChildProps)), + (nextProps.subtreeFlags = suspenseContext.subtreeFlags & 14680064)); + null !== JSCompiler_temp + ? (showFallback = createWorkInProgress(JSCompiler_temp, showFallback)) + : ((showFallback = createFiberFromFragment( + showFallback, + didSuspend, + renderLanes, + null + )), + (showFallback.flags |= 2)); + showFallback.return = workInProgress; + nextProps.return = workInProgress; + nextProps.sibling = showFallback; + workInProgress.child = nextProps; + nextProps = showFallback; + showFallback = workInProgress.child; + didSuspend = current.child.memoizedState; + didSuspend = + null === didSuspend + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: didSuspend.baseLanes | renderLanes, + cachePool: null, + transitions: didSuspend.transitions + }; + showFallback.memoizedState = didSuspend; + showFallback.childLanes = current.childLanes & ~renderLanes; + workInProgress.memoizedState = SUSPENDED_MARKER; + return nextProps; } - if (showFallback) - return ( - (showFallback = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (nextProps = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (nextProps.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (nextProps.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - showFallback - ); - renderLanes = updateSuspensePrimaryChildren( - current, - workInProgress, - nextProps.children, - renderLanes - ); - workInProgress.memoizedState = null; - return renderLanes; -} -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - primaryChildren = createWorkInProgress(currentPrimaryChildFragment, { + showFallback = current.child; + current = showFallback.sibling; + nextProps = createWorkInProgress(showFallback, { mode: "visible", - children: primaryChildren + children: nextProps.children }); - 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); - primaryChildren.return = workInProgress; - primaryChildren.sibling = null; + 0 === (workInProgress.mode & 1) && (nextProps.lanes = renderLanes); + nextProps.return = workInProgress; + nextProps.sibling = null; null !== current && ((renderLanes = workInProgress.deletions), null === renderLanes ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) : renderLanes.push(current)); + workInProgress.child = nextProps; + workInProgress.memoizedState = null; + return nextProps; +} +function mountSuspensePrimaryChildren(workInProgress, primaryChildren) { + primaryChildren = createFiberFromOffscreen( + { mode: "visible", children: primaryChildren }, + workInProgress.mode, + 0, + null + ); + primaryChildren.return = workInProgress; return (workInProgress.child = primaryChildren); } -function updateSuspenseFallbackChildren( +function retrySuspenseComponentWithoutHydrating( current, workInProgress, - primaryChildren, - fallbackChildren, + renderLanes, + recoverableError +) { + null !== recoverableError && + (null === hydrationErrors + ? (hydrationErrors = [recoverableError]) + : hydrationErrors.push(recoverableError)); + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + current = mountSuspensePrimaryChildren( + workInProgress, + workInProgress.pendingProps.children + ); + current.flags |= 2; + workInProgress.memoizedState = null; + return current; +} +function updateDehydratedSuspenseComponent( + current, + workInProgress, + didSuspend, + nextProps, + suspenseInstance, + suspenseState, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, - primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current - ? ((primaryChildren = workInProgress.child), - (primaryChildren.childLanes = 0), - (primaryChildren.pendingProps = primaryChildProps), - workInProgress.mode & 2 && - ((primaryChildren.actualDuration = 0), - (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = current.selfBaseDuration), - (primaryChildren.treeBaseDuration = current.treeBaseDuration)), - (workInProgress.deletions = null)) - : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 14680064)); - null !== currentFallbackChildFragment - ? (fallbackChildren = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - )) - : ((fallbackChildren = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, + if (didSuspend) { + if (workInProgress.flags & 256) + return ( + (workInProgress.flags &= -257), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + Error( + "There was an error while hydrating this Suspense boundary. Switched to client rendering." + ) + ) + ); + if (null !== workInProgress.memoizedState) + return ( + (workInProgress.child = current.child), + (workInProgress.flags |= 128), null - )), - (fallbackChildren.flags |= 2)); - fallbackChildren.return = workInProgress; - primaryChildren.return = workInProgress; - primaryChildren.sibling = fallbackChildren; - workInProgress.child = primaryChildren; - return fallbackChildren; + ); + suspenseState = nextProps.fallback; + didSuspend = workInProgress.mode; + nextProps = createFiberFromOffscreen( + { mode: "visible", children: nextProps.children }, + didSuspend, + 0, + null + ); + suspenseState = createFiberFromFragment( + suspenseState, + didSuspend, + renderLanes, + null + ); + suspenseState.flags |= 2; + nextProps.return = workInProgress; + suspenseState.return = workInProgress; + nextProps.sibling = suspenseState; + workInProgress.child = nextProps; + 0 !== (workInProgress.mode & 1) && + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return suspenseState; + } + if (0 === (workInProgress.mode & 1)) + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + null + ); + if (shim()) + return ( + (suspenseState = shim().errorMessage), + retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + suspenseState + ? Error(suspenseState) + : Error( + "The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering." + ) + ) + ); + didSuspend = 0 !== (renderLanes & current.childLanes); + if (didReceiveUpdate || didSuspend) { + nextProps = workInProgressRoot; + if (null !== nextProps) { + switch (renderLanes & -renderLanes) { + case 4: + didSuspend = 2; + break; + case 16: + didSuspend = 8; + break; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + didSuspend = 32; + break; + case 536870912: + didSuspend = 268435456; + break; + default: + didSuspend = 0; + } + nextProps = + 0 !== (didSuspend & (nextProps.suspendedLanes | renderLanes)) + ? 0 + : didSuspend; + 0 !== nextProps && + nextProps !== suspenseState.retryLane && + ((suspenseState.retryLane = nextProps), + scheduleUpdateOnFiber(current, nextProps, -1)); + } + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current, + workInProgress, + renderLanes, + Error( + "This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition." + ) + ); + } + if (shim()) + return ( + (workInProgress.flags |= 128), + (workInProgress.child = current.child), + retryDehydratedSuspenseBoundary.bind(null, current), + shim(), + null + ); + current = mountSuspensePrimaryChildren(workInProgress, nextProps.children); + current.flags |= 4096; + return current; } function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { fiber.lanes |= renderLanes; @@ -5545,6 +5282,13 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { } return workInProgress.child; } +function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + 0 === (workInProgress.mode & 1) && + null !== current && + ((current.alternate = null), + (workInProgress.alternate = null), + (workInProgress.flags |= 2)); +} function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; @@ -5600,7 +5344,14 @@ function attemptEarlyBailoutIfNoScheduledUpdate( context.passiveEffectDuration = 0; break; case 13: - if (null !== workInProgress.memoizedState) { + context = workInProgress.memoizedState; + if (null !== context) { + if (null !== context.dehydrated) + return ( + push(suspenseStackCursor, suspenseStackCursor.current & 1), + (workInProgress.flags |= 128), + null + ); if (0 !== (renderLanes & workInProgress.child.childLanes)) return updateSuspenseComponent(current, workInProgress, renderLanes); push(suspenseStackCursor, suspenseStackCursor.current & 1); @@ -5641,6 +5392,471 @@ function attemptEarlyBailoutIfNoScheduledUpdate( } return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } +var appendAllChildren, + updateHostContainer, + updateHostComponent$1, + updateHostText$1; +appendAllChildren = function(parent, workInProgress) { + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); + else if (4 !== node.tag && null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +}; +updateHostContainer = function() {}; +updateHostComponent$1 = function(current, workInProgress, type, newProps) { + current.memoizedProps !== newProps && + (requiredContext(contextStackCursor$1.current), + (workInProgress.updateQueue = UPDATE_SIGNAL)) && + (workInProgress.flags |= 4); +}; +updateHostText$1 = function(current, workInProgress, oldText, newText) { + oldText !== newText && (workInProgress.flags |= 4); +}; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var lastTailNode$63 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === lastTailNode$63 + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (lastTailNode$63.sibling = null); + } +} +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + if (0 !== (completedWork.mode & 2)) { + for ( + var treeBaseDuration$65 = completedWork.selfBaseDuration, + child$66 = completedWork.child; + null !== child$66; + + ) + (newChildLanes |= child$66.lanes | child$66.childLanes), + (subtreeFlags |= child$66.subtreeFlags & 14680064), + (subtreeFlags |= child$66.flags & 14680064), + (treeBaseDuration$65 += child$66.treeBaseDuration), + (child$66 = child$66.sibling); + completedWork.treeBaseDuration = treeBaseDuration$65; + } else + for ( + treeBaseDuration$65 = completedWork.child; + null !== treeBaseDuration$65; + + ) + (newChildLanes |= + treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), + (subtreeFlags |= treeBaseDuration$65.subtreeFlags & 14680064), + (subtreeFlags |= treeBaseDuration$65.flags & 14680064), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + else if (0 !== (completedWork.mode & 2)) { + treeBaseDuration$65 = completedWork.actualDuration; + child$66 = completedWork.selfBaseDuration; + for (var child = completedWork.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (subtreeFlags |= child.subtreeFlags), + (subtreeFlags |= child.flags), + (treeBaseDuration$65 += child.actualDuration), + (child$66 += child.treeBaseDuration), + (child = child.sibling); + completedWork.actualDuration = treeBaseDuration$65; + completedWork.treeBaseDuration = child$66; + } else + for ( + treeBaseDuration$65 = completedWork.child; + null !== treeBaseDuration$65; + + ) + (newChildLanes |= + treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), + (subtreeFlags |= treeBaseDuration$65.subtreeFlags), + (subtreeFlags |= treeBaseDuration$65.flags), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + popTreeContext(workInProgress); + switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return bubbleProperties(workInProgress), null; + case 1: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 3: + return ( + (renderLanes = workInProgress.stateNode), + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + resetWorkInProgressVersions(), + renderLanes.pendingContext && + ((renderLanes.context = renderLanes.pendingContext), + (renderLanes.pendingContext = null)), + (null !== current && null !== current.child) || + null === current || + (current.memoizedState.isDehydrated && + 0 === (workInProgress.flags & 256)) || + ((workInProgress.flags |= 1024), + null !== hydrationErrors && + (queueRecoverableErrors(hydrationErrors), + (hydrationErrors = null))), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 5: + popHostContext(workInProgress); + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + renderLanes + ), + current.ref !== workInProgress.ref && (workInProgress.flags |= 512); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + bubbleProperties(workInProgress); + return null; + } + requiredContext(contextStackCursor$1.current); + current = allocateTag(); + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + type.validAttributes + ); + ReactNativePrivateInterface.UIManager.createView( + current, + type.uiViewClassName, + renderLanes, + updatePayload + ); + renderLanes = new ReactNativeFiberHostComponent( + current, + type, + workInProgress + ); + instanceCache.set(current, workInProgress); + instanceProps.set(current, newProps); + appendAllChildren(renderLanes, workInProgress, !1, !1); + workInProgress.stateNode = renderLanes; + finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 512); + } + bubbleProperties(workInProgress); + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText$1( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + if (!requiredContext(contextStackCursor$1.current).isInAParentText) + throw Error( + "Text strings must be rendered within a component." + ); + renderLanes = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + renderLanes, + "RCTRawText", + current, + { text: newProps } + ); + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; + } + bubbleProperties(workInProgress); + return null; + case 13: + pop(suspenseStackCursor); + newProps = workInProgress.memoizedState; + if ( + null === current || + (null !== current.memoizedState && + null !== current.memoizedState.dehydrated) + ) { + if (null !== newProps && null !== newProps.dehydrated) { + if (null === current) { + throw Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ); + throw Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + 0 === (workInProgress.flags & 128) && + (workInProgress.memoizedState = null); + workInProgress.flags |= 4; + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 2) && + null !== newProps && + ((type = workInProgress.child), + null !== type && + (workInProgress.treeBaseDuration -= type.treeBaseDuration)); + type = !1; + } else + null !== hydrationErrors && + (queueRecoverableErrors(hydrationErrors), (hydrationErrors = null)), + (type = !0); + if (!type) return workInProgress.flags & 65536 ? workInProgress : null; + } + if (0 !== (workInProgress.flags & 128)) + return ( + (workInProgress.lanes = renderLanes), + 0 !== (workInProgress.mode & 2) && + transferActualDuration(workInProgress), + workInProgress + ); + renderLanes = null !== newProps; + renderLanes !== (null !== current && null !== current.memoizedState) && + renderLanes && + ((workInProgress.child.flags |= 8192), + 0 !== (workInProgress.mode & 1) && + (null === current || 0 !== (suspenseStackCursor.current & 1) + ? 0 === workInProgressRootExitStatus && + (workInProgressRootExitStatus = 3) + : renderDidSuspendDelayIfPossible())); + null !== workInProgress.updateQueue && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 2) && + renderLanes && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); + return null; + case 4: + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 10: + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor); + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; + if (null === updatePayload) + if (newProps) cutOffTailIfNeeded(type, !1); + else { + if ( + 0 !== workInProgressRootExitStatus || + (null !== current && 0 !== (current.flags & 128)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)); + workInProgress.subtreeFlags = 0; + current = renderLanes; + for (renderLanes = workInProgress.child; null !== renderLanes; ) + (newProps = renderLanes), + (updatePayload = current), + (newProps.flags &= 14680066), + (type = newProps.alternate), + null === type + ? ((newProps.childLanes = 0), + (newProps.lanes = updatePayload), + (newProps.child = null), + (newProps.subtreeFlags = 0), + (newProps.memoizedProps = null), + (newProps.memoizedState = null), + (newProps.updateQueue = null), + (newProps.dependencies = null), + (newProps.stateNode = null), + (newProps.selfBaseDuration = 0), + (newProps.treeBaseDuration = 0)) + : ((newProps.childLanes = type.childLanes), + (newProps.lanes = type.lanes), + (newProps.child = type.child), + (newProps.subtreeFlags = 0), + (newProps.deletions = null), + (newProps.memoizedProps = type.memoizedProps), + (newProps.memoizedState = type.memoizedState), + (newProps.updateQueue = type.updateQueue), + (newProps.type = type.type), + (updatePayload = type.dependencies), + (newProps.dependencies = + null === updatePayload + ? null + : { + lanes: updatePayload.lanes, + firstContext: updatePayload.firstContext + }), + (newProps.selfBaseDuration = type.selfBaseDuration), + (newProps.treeBaseDuration = type.treeBaseDuration)), + (renderLanes = renderLanes.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2 + ); + return workInProgress.child; + } + current = current.sibling; + } + null !== type.tail && + now() > workInProgressRootRenderTargetTime && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + } + else { + if (!newProps) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.flags |= 128), + (newProps = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)), + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && + !updatePayload.alternate) + ) + return bubbleProperties(workInProgress), null; + } else + 2 * now() - type.renderingStartTime > + workInProgressRootRenderTargetTime && + 1073741824 !== renderLanes && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = type.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (type.last = updatePayload)); + } + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; + case 22: + case 23: + return ( + popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), + null !== current && + (null !== current.memoizedState) !== renderLanes && + (workInProgress.flags |= 8192), + renderLanes && 0 !== (workInProgress.mode & 1) + ? 0 !== (subtreeRenderLanes & 1073741824) && + (bubbleProperties(workInProgress), + workInProgress.subtreeFlags & 6 && (workInProgress.flags |= 8192)) + : bubbleProperties(workInProgress), + null + ); + case 24: + return null; + case 25: + return null; + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} function unwindWork(current, workInProgress) { popTreeContext(workInProgress); switch (workInProgress.tag) { @@ -5669,16 +5885,23 @@ function unwindWork(current, workInProgress) { case 5: return popHostContext(workInProgress), null; case 13: - return ( - pop(suspenseStackCursor), - (current = workInProgress.flags), - current & 65536 - ? ((workInProgress.flags = (current & -65537) | 128), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress) - : null - ); + pop(suspenseStackCursor); + current = workInProgress.memoizedState; + if ( + null !== current && + null !== current.dehydrated && + null === workInProgress.alternate + ) + throw Error( + "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." + ); + current = workInProgress.flags; + return current & 65536 + ? ((workInProgress.flags = (current & -65537) | 128), + 0 !== (workInProgress.mode & 2) && + transferActualDuration(workInProgress), + workInProgress) + : null; case 19: return pop(suspenseStackCursor), null; case 4: @@ -5810,77 +6033,13 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create$83 = effect.create; - effect.destroy = create$83(); + var create$81 = effect.create; + effect.destroy = create$81(); } effect = effect.next; } while (effect !== finishedWork); } } -function commitUnmount(finishedRoot, current, nearestMountedAncestor) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) - try { - injectedHook.onCommitFiberUnmount(rendererID, current); - } catch (err) {} - switch (current.tag) { - case 0: - case 11: - case 14: - case 15: - finishedRoot = current.updateQueue; - if ( - null !== finishedRoot && - ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) - ) { - var effect = (finishedRoot = finishedRoot.next); - do { - var _effect = effect, - destroy = _effect.destroy; - _effect = _effect.tag; - void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(current, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && - (current.mode & 2 - ? (startLayoutEffectTimer(), - safelyCallDestroy(current, nearestMountedAncestor, destroy), - recordLayoutEffectDuration(current)) - : safelyCallDestroy( - current, - nearestMountedAncestor, - destroy - ))); - effect = effect.next; - } while (effect !== finishedRoot); - } - break; - case 1: - safelyDetachRef(current, nearestMountedAncestor); - finishedRoot = current.stateNode; - if ("function" === typeof finishedRoot.componentWillUnmount) - try { - if ( - ((finishedRoot.props = current.memoizedProps), - (finishedRoot.state = current.memoizedState), - current.mode & 2) - ) - try { - startLayoutEffectTimer(), finishedRoot.componentWillUnmount(); - } finally { - recordLayoutEffectDuration(current); - } - else finishedRoot.componentWillUnmount(); - } catch (error) { - captureCommitPhaseError(current, nearestMountedAncestor, error); - } - break; - case 5: - safelyDetachRef(current, nearestMountedAncestor); - break; - case 4: - unmountHostComponents(finishedRoot, current, nearestMountedAncestor); - } -} function detachFiberAfterEffects(fiber) { var alternate = fiber.alternate; null !== alternate && @@ -5919,40 +6078,6 @@ function getHostSibling(fiber) { if (!(fiber.flags & 2)) return fiber.stateNode; } } -function commitPlacement(finishedWork) { - a: { - for (var parent = finishedWork.return; null !== parent; ) { - if (isHostParent(parent)) break a; - parent = parent.return; - } - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } - var parentFiber = parent; - switch (parentFiber.tag) { - case 5: - parent = parentFiber.stateNode; - parentFiber.flags & 32 && (parentFiber.flags &= -33); - parentFiber = getHostSibling(finishedWork); - insertOrAppendPlacementNode(finishedWork, parentFiber, parent); - break; - case 3: - case 4: - parent = parentFiber.stateNode.containerInfo; - parentFiber = getHostSibling(finishedWork); - insertOrAppendPlacementNodeIntoContainer( - finishedWork, - parentFiber, - parent - ); - break; - default: - throw Error( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." - ); - } -} function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { var tag = node.tag; if (5 === tag || 6 === tag) @@ -6033,194 +6158,171 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents( - finishedRoot$jscomp$0, - current, - nearestMountedAncestor$jscomp$0 +var hostParent = null, + hostParentIsContainer = !1; +function recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + parent ) { - for ( - var node = current, - currentParentIsValid = !1, - currentParent, - currentParentIsContainer; - ; - - ) { - if (!currentParentIsValid) { - currentParentIsValid = node.return; - a: for (;;) { - if (null === currentParentIsValid) - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - currentParent = currentParentIsValid.stateNode; - switch (currentParentIsValid.tag) { - case 5: - currentParentIsContainer = !1; - break a; - case 3: - currentParent = currentParent.containerInfo; - currentParentIsContainer = !0; - break a; - case 4: - currentParent = currentParent.containerInfo; - currentParentIsContainer = !0; - break a; - } - currentParentIsValid = currentParentIsValid.return; - } - currentParentIsValid = !0; - } - if (5 === node.tag || 6 === node.tag) { - a: for ( - var finishedRoot = finishedRoot$jscomp$0, - root = node, - nearestMountedAncestor = nearestMountedAncestor$jscomp$0, - node$jscomp$0 = root; - ; - - ) - if ( - (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), - null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) - ) - (node$jscomp$0.child.return = node$jscomp$0), - (node$jscomp$0 = node$jscomp$0.child); - else { - if (node$jscomp$0 === root) break a; - for (; null === node$jscomp$0.sibling; ) { - if (null === node$jscomp$0.return || node$jscomp$0.return === root) - break a; - node$jscomp$0 = node$jscomp$0.return; - } - node$jscomp$0.sibling.return = node$jscomp$0.return; - node$jscomp$0 = node$jscomp$0.sibling; - } - currentParentIsContainer - ? ((finishedRoot = currentParent), - recursivelyUncacheFiberNode(node.stateNode), - ReactNativePrivateInterface.UIManager.manageChildren( - finishedRoot, - [], - [], - [], - [], - [0] - )) - : ((finishedRoot = currentParent), - (nearestMountedAncestor = node.stateNode), - recursivelyUncacheFiberNode(nearestMountedAncestor), - (root = finishedRoot._children), - (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), - root.splice(nearestMountedAncestor, 1), - ReactNativePrivateInterface.UIManager.manageChildren( - finishedRoot._nativeTag, - [], - [], - [], - [], - [nearestMountedAncestor] - )); - } else if (4 === node.tag) { - if (null !== node.child) { - currentParent = node.stateNode.containerInfo; - currentParentIsContainer = !0; - node.child.return = node; - node = node.child; - continue; - } - } else if ( - (commitUnmount( - finishedRoot$jscomp$0, - node, - nearestMountedAncestor$jscomp$0 - ), - null !== node.child) - ) { - node.child.return = node; - node = node.child; - continue; - } - if (node === current) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === current) return; - node = node.return; - 4 === node.tag && (currentParentIsValid = !1); - } - node.sibling.return = node.return; - node = node.sibling; - } + for (parent = parent.child; null !== parent; ) + commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, parent), + (parent = parent.sibling); } -function commitWork(current, finishedWork) { - switch (finishedWork.tag) { +function commitDeletionEffectsOnFiber( + finishedRoot, + nearestMountedAncestor, + deletedFiber +) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) + try { + injectedHook.onCommitFiberUnmount(rendererID, deletedFiber); + } catch (err) {} + switch (deletedFiber.tag) { + case 5: + safelyDetachRef(deletedFiber, nearestMountedAncestor); + case 6: + var prevHostParent = hostParent, + prevHostParentIsContainer = hostParentIsContainer; + hostParent = null; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + hostParent = prevHostParent; + hostParentIsContainer = prevHostParentIsContainer; + null !== hostParent && + (hostParentIsContainer + ? ((finishedRoot = hostParent), + recursivelyUncacheFiberNode(deletedFiber.stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + finishedRoot, + [], + [], + [], + [], + [0] + )) + : ((finishedRoot = hostParent), + (nearestMountedAncestor = deletedFiber.stateNode), + recursivelyUncacheFiberNode(nearestMountedAncestor), + (deletedFiber = finishedRoot._children), + (nearestMountedAncestor = deletedFiber.indexOf( + nearestMountedAncestor + )), + deletedFiber.splice(nearestMountedAncestor, 1), + ReactNativePrivateInterface.UIManager.manageChildren( + finishedRoot._nativeTag, + [], + [], + [], + [], + [nearestMountedAncestor] + ))); + break; + case 18: + null !== hostParent && shim(hostParent, deletedFiber.stateNode); + break; + case 4: + prevHostParent = hostParent; + prevHostParentIsContainer = hostParentIsContainer; + hostParent = deletedFiber.stateNode.containerInfo; + hostParentIsContainer = !0; + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + hostParent = prevHostParent; + hostParentIsContainer = prevHostParentIsContainer; + break; case 0: case 11: case 14: case 15: - commitHookEffectListUnmount(3, finishedWork, finishedWork.return); - commitHookEffectListMount(3, finishedWork); - if (finishedWork.mode & 2) - try { - startLayoutEffectTimer(), - commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - } finally { - recordLayoutEffectDuration(finishedWork); - } - else commitHookEffectListUnmount(5, finishedWork, finishedWork.return); - return; - case 1: - return; - case 5: - var instance = finishedWork.stateNode; - if (null != instance) { - var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; - var updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; - null !== updatePayload && - ((finishedWork = instance.viewConfig), - instanceProps.set(instance._nativeTag, newProps), - (newProps = diffProperties( - null, - current, - newProps, - finishedWork.validAttributes - )), - null != newProps && - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - finishedWork.uiViewClassName, - newProps - )); + prevHostParent = deletedFiber.updateQueue; + if ( + null !== prevHostParent && + ((prevHostParent = prevHostParent.lastEffect), null !== prevHostParent) + ) { + prevHostParentIsContainer = prevHostParent = prevHostParent.next; + do { + var _effect = prevHostParentIsContainer, + destroy = _effect.destroy; + _effect = _effect.tag; + void 0 !== destroy && + (0 !== (_effect & 2) + ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) + : 0 !== (_effect & 4) && + (deletedFiber.mode & 2 + ? (startLayoutEffectTimer(), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ), + recordLayoutEffectDuration(deletedFiber)) + : safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ))); + prevHostParentIsContainer = prevHostParentIsContainer.next; + } while (prevHostParentIsContainer !== prevHostParent); } - return; - case 6: - if (null === finishedWork.stateNode) - throw Error( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - ReactNativePrivateInterface.UIManager.updateView( - finishedWork.stateNode, - "RCTRawText", - { text: finishedWork.memoizedProps } + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 1: + safelyDetachRef(deletedFiber, nearestMountedAncestor); + prevHostParent = deletedFiber.stateNode; + if ("function" === typeof prevHostParent.componentWillUnmount) + try { + if ( + ((prevHostParent.props = deletedFiber.memoizedProps), + (prevHostParent.state = deletedFiber.memoizedState), + deletedFiber.mode & 2) + ) + try { + startLayoutEffectTimer(), prevHostParent.componentWillUnmount(); + } finally { + recordLayoutEffectDuration(deletedFiber); + } + else prevHostParent.componentWillUnmount(); + } catch (error) { + captureCommitPhaseError(deletedFiber, nearestMountedAncestor, error); + } + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 21: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + case 22: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber + ); + break; + default: + recursivelyTraverseDeletionEffects( + finishedRoot, + nearestMountedAncestor, + deletedFiber ); - return; - case 3: - return; - case 12: - return; - case 13: - attachSuspenseRetryListeners(finishedWork); - return; - case 19: - attachSuspenseRetryListeners(finishedWork); - return; - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } function attachSuspenseRetryListeners(finishedWork) { var wakeables = finishedWork.updateQueue; @@ -6245,164 +6347,331 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function commitMutationEffects(root, firstChild, committedLanes) { +function commitMutationEffects(root, finishedWork, committedLanes) { inProgressLanes = committedLanes; inProgressRoot = root; - for (nextEffect = firstChild; null !== nextEffect; ) { - firstChild = nextEffect; - committedLanes = firstChild.deletions; - if (null !== committedLanes) - for (var i = 0; i < committedLanes.length; i++) { - var childToDelete = committedLanes[i]; - try { - unmountHostComponents(root, childToDelete, firstChild); - var alternate = childToDelete.alternate; - null !== alternate && (alternate.return = null); - childToDelete.return = null; - } catch (error) { - captureCommitPhaseError(childToDelete, firstChild, error); - } - } - committedLanes = firstChild.child; - if (0 !== (firstChild.subtreeFlags & 12854) && null !== committedLanes) - (committedLanes.return = firstChild), (nextEffect = committedLanes); - else - for (; null !== nextEffect; ) { - firstChild = nextEffect; - try { - var flags = firstChild.flags; - if (flags & 512) { - var current = firstChild.alternate; - if (null !== current) { - committedLanes = current; - var currentRef = committedLanes.ref; - if (null !== currentRef) - if ("function" === typeof currentRef) - if (committedLanes.mode & 2) - try { - startLayoutEffectTimer(), currentRef(null); - } finally { - recordLayoutEffectDuration(committedLanes); - } - else currentRef(null); - else currentRef.current = null; - } - } - if (flags & 8192) - switch (firstChild.tag) { - case 13: - if (null !== firstChild.memoizedState) { - var current$92 = firstChild.alternate; - if (null === current$92 || null === current$92.memoizedState) - globalMostRecentFallbackTime = now(); - } - break; - case 22: - a: { - committedLanes = firstChild; - var isHidden = null !== firstChild.memoizedState; - i = null; - for (childToDelete = committedLanes; ; ) { - if (5 === childToDelete.tag) { - if (null === i) { - i = childToDelete; - var instance = childToDelete.stateNode; - if (isHidden) { - var instance$jscomp$0 = instance, - viewConfig = instance$jscomp$0.viewConfig; - var updatePayload = diffProperties( - null, - emptyObject, - { style: { display: "none" } }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance$jscomp$0._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } else { - var instance$jscomp$1 = childToDelete.stateNode, - props = childToDelete.memoizedProps, - viewConfig$jscomp$0 = instance$jscomp$1.viewConfig, - prevProps = assign({}, props, { - style: [props.style, { display: "none" }] - }); - var updatePayload$jscomp$0 = diffProperties( - null, - prevProps, - props, - viewConfig$jscomp$0.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance$jscomp$1._nativeTag, - viewConfig$jscomp$0.uiViewClassName, - updatePayload$jscomp$0 - ); - } - } - } else if (6 === childToDelete.tag) { - if (null === i) throw Error("Not yet implemented."); - } else if ( - ((22 !== childToDelete.tag && 23 !== childToDelete.tag) || - null === childToDelete.memoizedState || - childToDelete === committedLanes) && - null !== childToDelete.child - ) { - childToDelete.child.return = childToDelete; - childToDelete = childToDelete.child; - continue; - } - if (childToDelete === committedLanes) break; - for (; null === childToDelete.sibling; ) { - if ( - null === childToDelete.return || - childToDelete.return === committedLanes - ) - break a; - i === childToDelete && (i = null); - childToDelete = childToDelete.return; - } - i === childToDelete && (i = null); - childToDelete.sibling.return = childToDelete.return; - childToDelete = childToDelete.sibling; - } - } - } - switch (flags & 4102) { - case 2: - commitPlacement(firstChild); - firstChild.flags &= -3; - break; - case 6: - commitPlacement(firstChild); - firstChild.flags &= -3; - commitWork(firstChild.alternate, firstChild); - break; - case 4096: - firstChild.flags &= -4097; - break; - case 4100: - firstChild.flags &= -4097; - commitWork(firstChild.alternate, firstChild); - break; - case 4: - commitWork(firstChild.alternate, firstChild); - } - } catch (error) { - captureCommitPhaseError(firstChild, firstChild.return, error); - } - committedLanes = firstChild.sibling; - if (null !== committedLanes) { - committedLanes.return = firstChild.return; - nextEffect = committedLanes; - break; - } - nextEffect = firstChild.return; - } - } + commitMutationEffectsOnFiber(finishedWork, root); inProgressRoot = inProgressLanes = null; } +function recursivelyTraverseMutationEffects(root$jscomp$0, parentFiber) { + var deletions = parentFiber.deletions; + if (null !== deletions) + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; + try { + var root = root$jscomp$0, + returnFiber = parentFiber, + parent = returnFiber; + a: for (; null !== parent; ) { + switch (parent.tag) { + case 5: + hostParent = parent.stateNode; + hostParentIsContainer = !1; + break a; + case 3: + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = !0; + break a; + case 4: + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = !0; + break a; + } + parent = parent.return; + } + if (null === hostParent) + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + commitDeletionEffectsOnFiber(root, returnFiber, childToDelete); + hostParent = null; + hostParentIsContainer = !1; + var alternate = childToDelete.alternate; + null !== alternate && (alternate.return = null); + childToDelete.return = null; + } catch (error) { + captureCommitPhaseError(childToDelete, parentFiber, error); + } + } + if (parentFiber.subtreeFlags & 12854) + for (parentFiber = parentFiber.child; null !== parentFiber; ) + commitMutationEffectsOnFiber(parentFiber, root$jscomp$0), + (parentFiber = parentFiber.sibling); +} +function commitMutationEffectsOnFiber(finishedWork, root) { + var current = finishedWork.alternate, + flags = finishedWork.flags; + switch (finishedWork.tag) { + case 0: + case 11: + case 14: + case 15: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & 4) { + try { + commitHookEffectListUnmount(3, finishedWork, finishedWork.return), + commitHookEffectListMount(3, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + if (finishedWork.mode & 2) { + try { + startLayoutEffectTimer(), + commitHookEffectListUnmount(5, finishedWork, finishedWork.return); + } catch (error$93) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error$93 + ); + } + recordLayoutEffectDuration(finishedWork); + } else + try { + commitHookEffectListUnmount(5, finishedWork, finishedWork.return); + } catch (error$94) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error$94 + ); + } + } + break; + case 1: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 512 && + null !== current && + safelyDetachRef(current, current.return); + break; + case 5: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 512 && + null !== current && + safelyDetachRef(current, current.return); + if (flags & 4) { + var instance$96 = finishedWork.stateNode; + if (null != instance$96) { + var newProps = finishedWork.memoizedProps, + oldProps = null !== current ? current.memoizedProps : newProps, + updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; + if (null !== updatePayload) + try { + var viewConfig = instance$96.viewConfig; + instanceProps.set(instance$96._nativeTag, newProps); + var updatePayload$jscomp$0 = diffProperties( + null, + oldProps, + newProps, + viewConfig.validAttributes + ); + null != updatePayload$jscomp$0 && + ReactNativePrivateInterface.UIManager.updateView( + instance$96._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } catch (error$97) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error$97 + ); + } + } + } + break; + case 6: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & 4) { + if (null === finishedWork.stateNode) + throw Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ); + viewConfig = finishedWork.stateNode; + updatePayload$jscomp$0 = finishedWork.memoizedProps; + try { + ReactNativePrivateInterface.UIManager.updateView( + viewConfig, + "RCTRawText", + { text: updatePayload$jscomp$0 } + ); + } catch (error$98) { + captureCommitPhaseError(finishedWork, finishedWork.return, error$98); + } + } + break; + case 3: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 4: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + break; + case 13: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + viewConfig = finishedWork.child; + viewConfig.flags & 8192 && + null !== viewConfig.memoizedState && + (null === viewConfig.alternate || + null === viewConfig.alternate.memoizedState) && + (globalMostRecentFallbackTime = now()); + flags & 4 && attachSuspenseRetryListeners(finishedWork); + break; + case 22: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & 8192) + a: for ( + viewConfig = null !== finishedWork.memoizedState, + updatePayload$jscomp$0 = null, + current = finishedWork; + ; + + ) { + if (5 === current.tag) { + if (null === updatePayload$jscomp$0) { + updatePayload$jscomp$0 = current; + try { + if (((instance$96 = current.stateNode), viewConfig)) + (newProps = instance$96.viewConfig), + (oldProps = diffProperties( + null, + emptyObject, + { style: { display: "none" } }, + newProps.validAttributes + )), + ReactNativePrivateInterface.UIManager.updateView( + instance$96._nativeTag, + newProps.uiViewClassName, + oldProps + ); + else { + updatePayload = current.stateNode; + var props = current.memoizedProps, + viewConfig$jscomp$0 = updatePayload.viewConfig, + prevProps = assign({}, props, { + style: [props.style, { display: "none" }] + }); + var updatePayload$jscomp$1 = diffProperties( + null, + prevProps, + props, + viewConfig$jscomp$0.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig$jscomp$0.uiViewClassName, + updatePayload$jscomp$1 + ); + } + } catch (error) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error + ); + } + } + } else if (6 === current.tag) { + if (null === updatePayload$jscomp$0) + try { + throw Error("Not yet implemented."); + } catch (error$88) { + captureCommitPhaseError( + finishedWork, + finishedWork.return, + error$88 + ); + } + } else if ( + ((22 !== current.tag && 23 !== current.tag) || + null === current.memoizedState || + current === finishedWork) && + null !== current.child + ) { + current.child.return = current; + current = current.child; + continue; + } + if (current === finishedWork) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === finishedWork) + break a; + updatePayload$jscomp$0 === current && + (updatePayload$jscomp$0 = null); + current = current.return; + } + updatePayload$jscomp$0 === current && (updatePayload$jscomp$0 = null); + current.sibling.return = current.return; + current = current.sibling; + } + break; + case 19: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + flags & 4 && attachSuspenseRetryListeners(finishedWork); + break; + case 21: + break; + default: + recursivelyTraverseMutationEffects(root, finishedWork), + commitReconciliationEffects(finishedWork); + } +} +function commitReconciliationEffects(finishedWork) { + var flags = finishedWork.flags; + if (flags & 2) { + try { + a: { + for (var parent = finishedWork.return; null !== parent; ) { + if (isHostParent(parent)) { + var JSCompiler_inline_result = parent; + break a; + } + parent = parent.return; + } + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + } + switch (JSCompiler_inline_result.tag) { + case 5: + var parent$jscomp$0 = JSCompiler_inline_result.stateNode; + JSCompiler_inline_result.flags & 32 && + (JSCompiler_inline_result.flags &= -33); + var before = getHostSibling(finishedWork); + insertOrAppendPlacementNode(finishedWork, before, parent$jscomp$0); + break; + case 3: + case 4: + var parent$89 = JSCompiler_inline_result.stateNode.containerInfo, + before$90 = getHostSibling(finishedWork); + insertOrAppendPlacementNodeIntoContainer( + finishedWork, + before$90, + parent$89 + ); + break; + default: + throw Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + finishedWork.flags &= -3; + } + flags & 4096 && (finishedWork.flags &= -4097); +} function commitLayoutEffects(finishedWork, root, committedLanes) { inProgressLanes = committedLanes; inProgressRoot = root; @@ -6477,21 +6746,21 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { commitUpdateQueue(committedLanes, updateQueue, instance); break; case 3: - var updateQueue$85 = committedLanes.updateQueue; - if (null !== updateQueue$85) { - var instance$86 = null; + var updateQueue$83 = committedLanes.updateQueue; + if (null !== updateQueue$83) { + var instance$84 = null; if (null !== committedLanes.child) switch (committedLanes.child.tag) { case 5: - instance$86 = committedLanes.child.stateNode; + instance$84 = committedLanes.child.stateNode; break; case 1: - instance$86 = committedLanes.child.stateNode; + instance$84 = committedLanes.child.stateNode; } commitUpdateQueue( committedLanes, - updateQueue$85, - instance$86 + updateQueue$83, + instance$84 ); } break; @@ -6506,7 +6775,7 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { onCommit = _finishedWork$memoize2.onCommit, onRender = _finishedWork$memoize2.onRender, effectDuration = committedLanes.stateNode.effectDuration; - instance$86 = commitTime; + instance$84 = commitTime; current = null === current ? "mount" : "update"; currentUpdateIsNested && (current = "nested-update"); "function" === typeof onRender && @@ -6516,14 +6785,14 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { committedLanes.actualDuration, committedLanes.treeBaseDuration, committedLanes.actualStartTime, - instance$86 + instance$84 ); "function" === typeof onCommit && onCommit( committedLanes.memoizedProps.id, current, effectDuration, - instance$86 + instance$84 ); enqueuePendingPassiveProfilerEffect(committedLanes); var parentFiber = committedLanes.return; @@ -6546,6 +6815,7 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { case 21: case 22: case 23: + case 25: break; default: throw Error( @@ -6553,27 +6823,27 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { ); } if (committedLanes.flags & 512) { - instance$86 = void 0; + instance$84 = void 0; current = committedLanes; var ref = current.ref; if (null !== ref) { var instance$jscomp$0 = current.stateNode; switch (current.tag) { case 5: - instance$86 = instance$jscomp$0; + instance$84 = instance$jscomp$0; break; default: - instance$86 = instance$jscomp$0; + instance$84 = instance$jscomp$0; } if ("function" === typeof ref) if (current.mode & 2) try { - startLayoutEffectTimer(), ref(instance$86); + startLayoutEffectTimer(), ref(instance$84); } finally { recordLayoutEffectDuration(current); } - else ref(instance$86); - else ref.current = instance$86; + else ref(instance$84); + else ref.current = instance$84; } } } catch (error) { @@ -6588,10 +6858,10 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { nextEffect = null; break; } - instance$86 = committedLanes.sibling; - if (null !== instance$86) { - instance$86.return = committedLanes.return; - nextEffect = instance$86; + instance$84 = committedLanes.sibling; + if (null !== instance$84) { + instance$84.return = committedLanes.return; + nextEffect = instance$84; break; } nextEffect = committedLanes.return; @@ -6617,6 +6887,7 @@ var ceil = Math.ceil, workInProgressRootRecoverableErrors = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, + workInProgressTransitions = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -6642,10 +6913,7 @@ function requestUpdateLane(fiber) { if (null !== ReactCurrentBatchConfig.transition) return ( 0 === currentEventTransitionLane && - ((fiber = nextTransitionLane), - (nextTransitionLane <<= 1), - 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64), - (currentEventTransitionLane = fiber)), + (currentEventTransitionLane = claimNextTransitionLane()), currentEventTransitionLane ); fiber = currentUpdatePriority; @@ -6689,6 +6957,13 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { (sourceFiber = sourceFiber.return); return 3 === alternate.tag ? alternate.stateNode : null; } +function isInterleavedUpdate(fiber) { + return ( + (null !== workInProgressRoot || null !== interleavedQueues) && + 0 !== (fiber.mode & 1) && + 0 === (executionContext & 2) + ); +} function ensureRootIsScheduled(root, currentTime) { for ( var existingCallbackNode = root.callbackNode, @@ -6792,6 +7067,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { memoizedUpdaters.clear()); movePendingFibersToMemoized(root, didTimeout); } + workInProgressTransitions = null; workInProgressRootRenderTargetTime = now() + 500; prepareFreshStack(root, didTimeout); } @@ -6850,7 +7126,11 @@ function performConcurrentWorkOnRoot(root, didTimeout) { case 1: throw Error("Root did not complete. This is a bug in React."); case 2: - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 3: markRootSuspended$1(root, lanes); @@ -6867,12 +7147,21 @@ function performConcurrentWorkOnRoot(root, didTimeout) { break; } root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), didTimeout ); break; } - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 4: markRootSuspended$1(root, lanes); @@ -6903,15 +7192,28 @@ function performConcurrentWorkOnRoot(root, didTimeout) { : 1960 * ceil(lanes / 1960)) - lanes; if (10 < lanes) { root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, workInProgressRootRecoverableErrors), + commitRoot.bind( + null, + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ), lanes ); break; } - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; case 5: - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); break; default: throw Error("Unknown root exit status."); @@ -6931,15 +7233,17 @@ function recoverFromConcurrentError(root, errorRetryLanes) { 2 !== root && ((errorRetryLanes = workInProgressRootRecoverableErrors), (workInProgressRootRecoverableErrors = errorsFromFirstAttempt), - null !== errorRetryLanes && - (null === workInProgressRootRecoverableErrors - ? (workInProgressRootRecoverableErrors = errorRetryLanes) - : workInProgressRootRecoverableErrors.push.apply( - workInProgressRootRecoverableErrors, - errorRetryLanes - ))); + null !== errorRetryLanes && queueRecoverableErrors(errorRetryLanes)); return root; } +function queueRecoverableErrors(errors) { + null === workInProgressRootRecoverableErrors + ? (workInProgressRootRecoverableErrors = errors) + : workInProgressRootRecoverableErrors.push.apply( + workInProgressRootRecoverableErrors, + errors + ); +} function isRenderConsistentWithExternalStores(finishedWork) { for (var node = finishedWork; ; ) { if (node.flags & 16384) { @@ -7011,7 +7315,11 @@ function performSyncWorkOnRoot(root) { throw Error("Root did not complete. This is a bug in React."); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - commitRoot(root, workInProgressRootRecoverableErrors); + commitRoot( + root, + workInProgressRootRecoverableErrors, + workInProgressTransitions + ); ensureRootIsScheduled(root, now()); return null; } @@ -7250,12 +7558,12 @@ function handleError(root$jscomp$0, thrownValue) { root.flags |= 65536; thrownValue &= -thrownValue; root.lanes |= thrownValue; - var update$35 = createClassErrorUpdate( + var update$36 = createClassErrorUpdate( root, wakeable, thrownValue ); - enqueueCapturedUpdate(root, update$35); + enqueueCapturedUpdate(root, update$36); break a; } } @@ -7302,6 +7610,7 @@ function renderRootSync(root, lanes) { memoizedUpdaters.clear()); movePendingFibersToMemoized(root, lanes); } + workInProgressTransitions = null; prepareFreshStack(root, lanes); } do @@ -7396,50 +7705,60 @@ function completeUnitOfWork(unitOfWork) { } while (null !== completedWork); 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } -function commitRoot(root, recoverableErrors) { +function commitRoot(root, recoverableErrors, transitions) { var previousUpdateLanePriority = currentUpdatePriority, prevTransition = ReactCurrentBatchConfig$2.transition; try { (ReactCurrentBatchConfig$2.transition = null), (currentUpdatePriority = 1), - commitRootImpl(root, recoverableErrors, previousUpdateLanePriority); + commitRootImpl( + root, + recoverableErrors, + transitions, + previousUpdateLanePriority + ); } finally { (ReactCurrentBatchConfig$2.transition = prevTransition), (currentUpdatePriority = previousUpdateLanePriority); } return null; } -function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { +function commitRootImpl( + root, + recoverableErrors, + transitions, + renderPriorityLevel +) { do flushPassiveEffects(); while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 6)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; - if (null === finishedWork) return null; + transitions = root.finishedWork; + var lanes = root.finishedLanes; + if (null === transitions) return null; root.finishedWork = null; root.finishedLanes = 0; - if (finishedWork === root.current) + if (transitions === root.current) throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; root.callbackPriority = 0; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + var remainingLanes = transitions.lanes | transitions.childLanes; markRootFinished(root, remainingLanes); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 2064) && - 0 === (finishedWork.flags & 2064)) || + (0 === (transitions.subtreeFlags & 2064) && + 0 === (transitions.flags & 2064)) || rootDoesHavePassiveEffects || ((rootDoesHavePassiveEffects = !0), scheduleCallback$1(NormalPriority, function() { flushPassiveEffects(); return null; })); - remainingLanes = 0 !== (finishedWork.flags & 15990); - if (0 !== (finishedWork.subtreeFlags & 15990) || remainingLanes) { + remainingLanes = 0 !== (transitions.flags & 15990); + if (0 !== (transitions.subtreeFlags & 15990) || remainingLanes) { remainingLanes = ReactCurrentBatchConfig$2.transition; ReactCurrentBatchConfig$2.transition = null; var previousPriority = currentUpdatePriority; @@ -7447,32 +7766,32 @@ function commitRootImpl(root, recoverableErrors, renderPriorityLevel) { var prevExecutionContext = executionContext; executionContext |= 4; ReactCurrentOwner$2.current = null; - commitBeforeMutationEffects(root, finishedWork); + commitBeforeMutationEffects(root, transitions); commitTime = now$1(); - commitMutationEffects(root, finishedWork, lanes); - root.current = finishedWork; - commitLayoutEffects(finishedWork, root, lanes); + commitMutationEffects(root, transitions, lanes); + root.current = transitions; + commitLayoutEffects(transitions, root, lanes); requestPaint(); executionContext = prevExecutionContext; currentUpdatePriority = previousPriority; ReactCurrentBatchConfig$2.transition = remainingLanes; - } else (root.current = finishedWork), (commitTime = now$1()); + } else (root.current = transitions), (commitTime = now$1()); rootDoesHavePassiveEffects && ((rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + onCommitRoot(transitions.stateNode, renderPriorityLevel); isDevToolsPresent && root.memoizedUpdaters.clear(); ensureRootIsScheduled(root, now()); if (null !== recoverableErrors) for ( - renderPriorityLevel = root.onRecoverableError, finishedWork = 0; - finishedWork < recoverableErrors.length; - finishedWork++ + renderPriorityLevel = root.onRecoverableError, transitions = 0; + transitions < recoverableErrors.length; + transitions++ ) - renderPriorityLevel(recoverableErrors[finishedWork]); + renderPriorityLevel(recoverableErrors[transitions]); if (hasUncaughtError) throw ((hasUncaughtError = !1), (root = firstUncaughtError), @@ -7773,21 +8092,43 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { : (workInProgressRootPingedLanes |= pingedLanes)); ensureRootIsScheduled(root, wakeable); } -function resolveRetryWakeable(boundaryFiber, wakeable) { - var retryCache = boundaryFiber.stateNode; - null !== retryCache && retryCache.delete(wakeable); - wakeable = 0; - 0 === wakeable && +function retryTimedOutBoundary(boundaryFiber, retryLane) { + 0 === retryLane && (0 === (boundaryFiber.mode & 1) - ? (wakeable = 1) - : ((wakeable = nextRetryLane), + ? (retryLane = 1) + : ((retryLane = nextRetryLane), (nextRetryLane <<= 1), 0 === (nextRetryLane & 130023424) && (nextRetryLane = 4194304))); - retryCache = requestEventTime(); - boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); + var eventTime = requestEventTime(); + boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane); null !== boundaryFiber && - (markRootUpdated(boundaryFiber, wakeable, retryCache), - ensureRootIsScheduled(boundaryFiber, retryCache)); + (markRootUpdated(boundaryFiber, retryLane, eventTime), + ensureRootIsScheduled(boundaryFiber, eventTime)); +} +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState, + retryLane = 0; + null !== suspenseState && (retryLane = suspenseState.retryLane); + retryTimedOutBoundary(boundaryFiber, retryLane); +} +function resolveRetryWakeable(boundaryFiber, wakeable) { + var retryLane = 0; + switch (boundaryFiber.tag) { + case 13: + var retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + null !== suspenseState && (retryLane = suspenseState.retryLane); + break; + case 19: + retryCache = boundaryFiber.stateNode; + break; + default: + throw Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ); + } + null !== retryCache && retryCache.delete(wakeable); + retryTimedOutBoundary(boundaryFiber, retryLane); } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { @@ -7817,10 +8158,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { switch (workInProgress.tag) { case 2: var Component = workInProgress.type; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; var context = getMaskedContext( workInProgress, @@ -7874,10 +8212,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 16: Component = workInProgress.elementType; a: { - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); current = workInProgress.pendingProps; context = Component._init; Component = context(Component._payload); @@ -7983,7 +8318,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return ( pushHostContext(workInProgress), (Component = workInProgress.pendingProps.children), - markRef$1(current, workInProgress), + markRef(current, workInProgress), reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); @@ -8081,24 +8416,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - newValue = workInProgress.child, - null !== newValue && (newValue.return = workInProgress); - null !== newValue; + hasContext = workInProgress.child, + null !== hasContext && (hasContext.return = workInProgress); + null !== hasContext; ) { - var list = newValue.dependencies; + var list = hasContext.dependencies; if (null !== list) { - hasContext = newValue.child; + newValue = hasContext.child; for ( var dependency = list.firstContext; null !== dependency; ) { if (dependency.context === Component) { - if (1 === newValue.tag) { + if (1 === hasContext.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; - var updateQueue = newValue.updateQueue; + var updateQueue = hasContext.updateQueue; if (null !== updateQueue) { updateQueue = updateQueue.shared; var pending = updateQueue.pending; @@ -8109,11 +8444,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateQueue.pending = dependency; } } - newValue.lanes |= renderLanes; - dependency = newValue.alternate; + hasContext.lanes |= renderLanes; + dependency = hasContext.alternate; null !== dependency && (dependency.lanes |= renderLanes); scheduleContextWorkOnParentPath( - newValue.return, + hasContext.return, renderLanes, workInProgress ); @@ -8122,29 +8457,43 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } dependency = dependency.next; } - } else - hasContext = - 10 === newValue.tag - ? newValue.type === workInProgress.type - ? null - : newValue.child - : newValue.child; - if (null !== hasContext) hasContext.return = newValue; + } else if (10 === hasContext.tag) + newValue = + hasContext.type === workInProgress.type + ? null + : hasContext.child; + else if (18 === hasContext.tag) { + newValue = hasContext.return; + if (null === newValue) + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + newValue.lanes |= renderLanes; + list = newValue.alternate; + null !== list && (list.lanes |= renderLanes); + scheduleContextWorkOnParentPath( + newValue, + renderLanes, + workInProgress + ); + newValue = hasContext.sibling; + } else newValue = hasContext.child; + if (null !== newValue) newValue.return = hasContext; else - for (hasContext = newValue; null !== hasContext; ) { - if (hasContext === workInProgress) { - hasContext = null; + for (newValue = hasContext; null !== newValue; ) { + if (newValue === workInProgress) { + newValue = null; break; } - newValue = hasContext.sibling; - if (null !== newValue) { - newValue.return = hasContext.return; - hasContext = newValue; + hasContext = newValue.sibling; + if (null !== hasContext) { + hasContext.return = newValue.return; + newValue = hasContext; break; } - hasContext = hasContext.return; + newValue = newValue.return; } - newValue = hasContext; + hasContext = newValue; } reconcileChildren( current, @@ -8195,10 +8544,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress.elementType === Component ? context : resolveDefaultProps(Component, context)), - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.flags |= 2)), + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress), (workInProgress.tag = 1), isContextProvider(Component) ? ((current = !0), pushContextProvider(workInProgress)) @@ -8563,10 +8909,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1003 = { + devToolsConfig$jscomp$inline_1010 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "18.0.0-experimental-34aa5cfe0-20220329", + version: "18.2.0-next-d300cebde-20220601", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8581,11 +8927,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1277 = { - bundleType: devToolsConfig$jscomp$inline_1003.bundleType, - version: devToolsConfig$jscomp$inline_1003.version, - rendererPackageName: devToolsConfig$jscomp$inline_1003.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1003.rendererConfig, +var internals$jscomp$inline_1302 = { + bundleType: devToolsConfig$jscomp$inline_1010.bundleType, + version: devToolsConfig$jscomp$inline_1010.version, + rendererPackageName: devToolsConfig$jscomp$inline_1010.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1010.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8601,26 +8947,26 @@ var internals$jscomp$inline_1277 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1003.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1010.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.0.0-experimental-34aa5cfe0-20220329" + reconcilerVersion: "18.2.0-next-d300cebde-20220601" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1278 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1303 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1278.isDisabled && - hook$jscomp$inline_1278.supportsFiber + !hook$jscomp$inline_1303.isDisabled && + hook$jscomp$inline_1303.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1278.inject( - internals$jscomp$inline_1277 + (rendererID = hook$jscomp$inline_1303.inject( + internals$jscomp$inline_1302 )), - (injectedHook = hook$jscomp$inline_1278); + (injectedHook = hook$jscomp$inline_1303); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -8682,7 +9028,8 @@ exports.render = function(element, containerTag, callback) { element: null, isDehydrated: !1, cache: null, - transitions: null + transitions: null, + pendingSuspenseBoundaries: null }; initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); diff --git a/package.json b/package.json index 9a5909bbe52..f68f1854ad7 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "repo-config" ], "peerDependencies": { - "react": "18.0.0" + "react": "18.1.0" }, "dependencies": { "@jest/create-cache-key-function": "^27.0.1", @@ -130,9 +130,9 @@ "react-devtools-core": "4.24.0", "react-native-gradle-plugin": "^0.0.7", "react-refresh": "^0.4.0", - "react-shallow-renderer": "16.14.1", + "react-shallow-renderer": "^16.15.0", "regenerator-runtime": "^0.13.2", - "scheduler": "^0.21.0", + "scheduler": "^0.22.0", "stacktrace-parser": "^0.1.3", "use-sync-external-store": "^1.0.0", "whatwg-fetch": "^3.0.0", @@ -140,8 +140,8 @@ }, "devDependencies": { "flow-bin": "^0.179.0", - "react": "18.0.0", - "react-test-renderer": "^18.0.0" + "react": "18.1.0", + "react-test-renderer": "^18.1.0" }, "codegenConfig": { "libraries": [ diff --git a/packages/rn-tester/package.json b/packages/rn-tester/package.json index 6fbbfdb387c..aa37800cc1b 100644 --- a/packages/rn-tester/package.json +++ b/packages/rn-tester/package.json @@ -23,7 +23,7 @@ "nullthrows": "^1.1.1" }, "peerDependencies": { - "react": "18.0.0", + "react": "18.1.0", "react-native": "*" }, "devDependencies": { diff --git a/repo-config/package.json b/repo-config/package.json index 7380ee93f12..76fc9111cb6 100644 --- a/repo-config/package.json +++ b/repo-config/package.json @@ -43,9 +43,9 @@ "metro-memory-fs": "0.71.0", "mkdirp": "^0.5.1", "prettier": "^2.4.1", - "react": "18.0.0", + "react": "18.1.0", "react-native-codegen": "^0.70.0", - "react-test-renderer": "18.0.0", + "react-test-renderer": "18.1.0", "shelljs": "^0.8.5", "signedsource": "^1.0.0", "ws": "^6.1.4", diff --git a/template/package.json b/template/package.json index daf46a72426..bb0dedf3d37 100644 --- a/template/package.json +++ b/template/package.json @@ -10,7 +10,7 @@ "lint": "eslint ." }, "dependencies": { - "react": "18.0.0", + "react": "18.1.0", "react-native": "1000.0.0" }, "devDependencies": { @@ -21,7 +21,7 @@ "eslint": "^7.32.0", "jest": "^26.6.3", "metro-react-native-babel-preset": "^0.71.0", - "react-test-renderer": "18.0.0" + "react-test-renderer": "18.1.0" }, "jest": { "preset": "react-native" diff --git a/yarn.lock b/yarn.lock index 4acfe144c05..2c62e6722cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5965,47 +5965,47 @@ react-devtools-core@4.24.0: shell-quote "^1.6.1" ws "^7" -"react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" + integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== react-is@^16.8.1, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.0.0.tgz#026f6c4a27dbe33bf4a35655b9e1327c4e55e3f5" - integrity sha512-yUcBYdBBbo3QiPsgYDcfQcIkGZHfxOaoE6HLSnr1sPzMhdyxusbfKOSUbSd/ocGi32dxcj366PsTj+5oggeKKw== +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== react-refresh@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.0.tgz#d421f9bd65e0e4b9822a399f14ac56bda9c92292" integrity sha512-bacjSio8GOtzNZKZZM6EWqbhlbb6pr28JWJWFTLwEBKvPIBRo6/Ob68D2EWZA2VyTdQxAh+TRnCYOPNKsQiXTA== -react-shallow-renderer@16.14.1, react-shallow-renderer@^16.13.1: - version "16.14.1" - resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz#bf0d02df8a519a558fd9b8215442efa5c840e124" - integrity sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg== +react-shallow-renderer@^16.15.0: + version "16.15.0" + resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457" + integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA== dependencies: object-assign "^4.1.1" - react-is "^16.12.0 || ^17.0.0" + react-is "^16.12.0 || ^17.0.0 || ^18.0.0" -react-test-renderer@18.0.0, react-test-renderer@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.0.0.tgz#fa403d625ea9478a70ace43db88833f6c3a5bb4c" - integrity sha512-SyZTP/FSkwfiKOZuTZiISzsrC8A80KNlQ8PyyoGoOq+VzMAab6Em1POK/CiX3+XyXG6oiJa1C53zYDbdrJu9fw== +react-test-renderer@18.1.0, react-test-renderer@^18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.1.0.tgz#35b75754834cf9ab517b6813db94aee0a6b545c3" + integrity sha512-OfuueprJFW7h69GN+kr4Ywin7stcuqaYAt1g7airM5cUgP0BoF5G5CXsPGmXeDeEkncb2fqYNECO4y18sSqphg== dependencies: - react-is "^18.0.0" - react-shallow-renderer "^16.13.1" - scheduler "^0.21.0" + react-is "^18.1.0" + react-shallow-renderer "^16.15.0" + scheduler "^0.22.0" -react@18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.0.0.tgz#b468736d1f4a5891f38585ba8e8fb29f91c3cb96" - integrity sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A== +react@18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890" + integrity sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ== dependencies: loose-envify "^1.1.0" @@ -6383,10 +6383,10 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -scheduler@^0.21.0: - version "0.21.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.21.0.tgz#6fd2532ff5a6d877b6edb12f00d8ab7e8f308820" - integrity sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ== +scheduler@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.22.0.tgz#83a5d63594edf074add9a7198b1bae76c3db01b8" + integrity sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ== dependencies: loose-envify "^1.1.0"